Copepod Collection

Copepods were collected at approximately weekly intervals from Lake Champlain (Burlington Fishing Pier). Plankton was collected from the top 3 meters using a 250 um mesh net.

# # Lake Champlain near Burlington, VT
# siteNumber = "04294500"
# ChamplainInfo = readNWISsite(siteNumber)
# parameterCd = "00010"
# startDate = "2023-01-01"
# endDate = "2024-5-20"
# #statCd = c("00001", "00002","00003", "00011") # 1 - max, 2 - min, 3 = mean
# 
# # Constructs the URL for the data wanted then downloads the data
# url = constructNWISURL(siteNumbers = siteNumber, parameterCd = parameterCd,
#                        startDate = startDate, endDate = endDate, service = "uv")
# 
# raw_temps = importWaterML1(url, asDateTime = T) %>%
#   mutate("date" = as.Date(dateTime),
#          "hour" = hour(dateTime)) %>%
#   select(dateTime, tz_cd, date, hour, degC = X_00010_00000)
# 
# temp_data =  raw_temps %>%
#   select(date, hour, "temp" = degC)
# 
# write.csv(temp_data, file = "./Output/Data/champlain_temps.csv", row.names = F)

Collections began in late May 2023. Several gaps are present, but collections have continued at roughly weekly intervals since then. Copepods from 48 collections were used to make a total of 1312 thermal limit measurements. Over this time period, collection temperatures ranged from 2.5 to 26.5°C.

There is substantial variation in thermal limits across the species collected. There is also some degree of variation within the species, with thermal limits increasing slightly during the summer.

## Daily values for the period examined by dataset
collection_conditions = temp_data %>%
  ungroup() %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp),
            med_temp = median(temp),
            var_temp = var(temp), 
            min_temp = min(temp), 
            max_temp = max(temp)) %>% 
  mutate("range_temp" = max_temp - min_temp,
         date = as.Date(date)) %>% 
  ungroup() %>%  
  filter(date >= (min(as.Date(full_data$collection_date)) - 7)) %>% 
  left_join(unique(select(full_data, collection_date, collection_temp)), by = join_by(date == collection_date))

## Mean female thermal limits for each species, grouped by collection
species_summaries = full_data %>%  
  #filter(sex == "female") %>% 
  group_by(sp_name, collection_date, collection_temp) %>%  
  summarise("mean_ctmax" = mean(ctmax),
            "sample_size" = n(),
            "ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
            "ctmax_var" = var(ctmax), 
            "mean_size" = mean(size),
            "size_st_err" = (sd(size) / sqrt(sample_size)),
            "size_var" = var(size)) %>%  
  ungroup() %>% 
  complete(sp_name, collection_date) %>% 
  arrange(desc(sample_size))

adult_summaries = full_data %>%  
  filter(sex == "female") %>% 
  group_by(sp_name, collection_date, collection_temp) %>%  
  summarise("mean_ctmax" = mean(ctmax),
            "sample_size" = n(),
            "ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
            "ctmax_var" = var(ctmax), 
            "mean_size" = mean(size),
            "size_st_err" = (sd(size) / sqrt(sample_size)),
            "size_var" = var(size)) %>%  
  ungroup() %>% 
  complete(sp_name, collection_date) %>% 
  arrange(desc(sample_size))


ggplot() + 
  geom_vline(data = unique(select(full_data, collection_date)), 
             aes(xintercept = as.Date(collection_date)),
             colour = "grey90",
             linewidth = 1) + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 2) + 
  # geom_errorbar(data = species_summaries,
  #               aes(x = as.Date(collection_date),
  #                   ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
  #                   colour = sp_name),
  #               position = position_dodge(width = 1),
  #               width = 5, linewidth = 1) +
  # geom_point(data = adult_summaries, 
  #            aes(x = as.Date(collection_date), y = mean_ctmax, colour = sp_name, size = sample_size)) + 
  geom_point(data = full_data, 
             aes(x = as.Date(collection_date), y = ctmax, colour = sp_name),
             size = 2, position = position_jitter(width = 1, height = 0)) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species",
       size = "Sample Size") + 
  theme_matt() + 
  theme(legend.position = "right")


lake_temps = ggplot() + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 1) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species",
       size = "Sample Size") + 
  theme_matt() + 
  theme(legend.position = "right")

Temperatures observed at the time of collection closely resembled the maximum daily temperature from the temperature sensor data. Maximum temperature was used as a proxy instead of mean temperature as collections were usually made during afternoons or early evenings, just following the warmest part of the day.

collection_conditions %>% 
  drop_na(collection_temp) %>%  
  ggplot(aes(x = max_temp, y = collection_temp)) + 
  geom_abline(intercept = 0, slope = 1,
              linewidth = 1, colour = "grey") + 
  geom_point(size = 3) +
  scale_x_continuous(breaks = c(5,15,25)) + 
  scale_y_continuous(breaks = c(5,15,25)) + 
  labs(x = "Max. Temp. from Sensor (°C)",
       y = "Collection Temp. (°C)") + 
  theme_matt()

Size also varied, but primarily between rather than within species.

ggplot() + 
  geom_vline(data = unique(select(full_data, collection_date)), 
             aes(xintercept = as.Date(collection_date)),
             colour = "grey90",
             linewidth = 1) + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 2) + 
  # geom_errorbar(data = species_summaries,
  #               aes(x = as.Date(collection_date), 
  #                   ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
  #                   colour = sp_name),
  #               position = position_dodge(width = 1),
  #               width = 5, linewidth = 1) + 
  geom_point(data = adult_summaries, 
             aes(x = as.Date(collection_date), y = mean_size * 40, colour = sp_name, size = sample_size),
             position = position_dodge(width = 1)) + 
  scale_colour_manual(values = species_cols) + 
  scale_y_continuous(
    name = "Temperature", # Features of the first axis
    sec.axis = sec_axis(~./40, name="Prosome Length (mm)"), # Add a second axis and specify its features
    breaks = c(0,5,10,15,20,25,30)
  ) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species") + 
  theme_matt() + 
  theme(legend.position = "right")

sample_dates_plot = full_data %>%  
  filter(sp_name != "Osphranticum labronectum") %>% 
  mutate(sp_name = as.factor(sp_name),
         sp_name = fct_reorder(sp_name, ctmax)) %>% 
  ggplot(aes(x = lubridate::as_date(collection_date), 
             y = sp_name, fill = sp_name)) + 
  # geom_vline(xintercept = as_date(
  #   c("2023-05-01",
  #     "2023-09-01",
  #     "2024-01-01",
  #     "2024-05-01")),
  #   colour = "grey",
  #   linewidth = 1) + 
  geom_density_ridges(bandwidth = 30,
                      jittered_points = TRUE, 
                      point_shape = 21,
                      point_size = 1,
                      point_colour = "grey30",
                      point_alpha = 0.6,
                      alpha = 0.9,
                      position = position_points_jitter(
                        height = 0.1, width = 0)) + 
  scale_fill_manual(values = species_cols) + 
  scale_x_date(date_breaks = "3 months",
               date_labels = "%b") + 
  coord_cartesian(xlim = lubridate::as_date(c("2023-04-25", "2024-06-01"))) + 
  labs(x = "Day of Year", 
       y = "Species") + 
  theme_matt() + 
  #theme_ridges(grid = T) + 
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))

The samples captured the broad seasonal changes in calanoid copepod community composition in the lake. We note, however, that rare species (e.g. Senecella and Limnocalanus) were often preferentially sampled, so are over-represented in the data set.

adult_summaries %>% 
  ungroup() %>% 
  mutate(collection_num = as.numeric(factor(collection_date))) %>% 
  group_by(collection_date) %>%  
  arrange(collection_date) %>% 
  select(sp_name, collection_date, collection_num, sample_size) %>% 
  mutate(sample_size = replace_na(sample_size, 0)) %>% 
  mutate(total = sum(sample_size),
         percentage = sample_size / total,
         collection_date = lubridate::as_date(collection_date)) %>% 
  ggplot(aes(x = collection_date, y = percentage, fill = sp_name)) + 
  geom_area() + 
  scale_fill_manual(values = species_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Species") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

Throughout the season, the prevalence of various unidentified pathogens also varied, with very little infection observed during the Winter and Spring.

pathogen_cols = c("no" = "grey95", "cloudy" = "honeydew3", "spot" = "antiquewhite3", "other" = "tomato3")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by() %>% 
  filter(sex != "juvenile") %>% 
  group_by(collection_date) %>% 
  count(pathogen) %>% 
  filter(pathogen != "uncertain") %>% 
  pivot_wider(id_cols = "collection_date", 
              names_from = pathogen, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, cloudy, spot, other)) %>% 
  pivot_longer(cols = c(no, cloudy, spot, other),
               names_to = "pathogen", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         pathogen = fct_relevel(pathogen, "no", "cloudy", "spot", "other")) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = pathogen)) + 
  geom_area() + 
  scale_fill_manual(values = pathogen_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Pathogen") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

The transparent bodies of these copepods also allowed us to examine seasonal patterns in lipid reserves and in the production of eggs. Maturing oocytes are visible in female copepods before they are released. There was no strong seasonal cycle in the production of these eggs in any species, and instead, females were reproductively active throughout their respective seasons of occurence.

dev_eggs_cols = c("no" = "grey95", "yes" = "lightblue3")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by(sp_name) %>% 
  filter(sex != "juvenile") %>% 
  group_by(sp_name, collection_date) %>% 
  count(dev_eggs) %>% 
  filter(dev_eggs != "uncertain") %>% 
  pivot_wider(id_cols = c("collection_date", "sp_name"), 
              names_from = dev_eggs, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, yes)) %>% 
  pivot_longer(cols = c(no, yes),
               names_to = "dev_eggs", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         dev_eggs = fct_relevel(dev_eggs, "no", "yes")) %>% 
  ungroup() %>% 
  complete(collection_date, nesting(sp_name, dev_eggs), fill = list(percent = 1)) %>% 
  mutate(percent = if_else(is.na(total) & dev_eggs == "yes", 0, percent)) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = dev_eggs)) + 
  facet_wrap(sp_name~., ncol = 1) + 
  geom_area() + 
  scale_fill_manual(values = dev_eggs_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Developing \nEggs") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

The presence of lipids varied across species, with only L. minutus, L. sicilis, and Limnocalanus regularly possessing lipid stores.

lipid_cols = c("no" = "grey95", "yes" = "sienna2")

full_data %>% 
  select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>% 
  group_by(sp_name) %>% 
  filter(sex != "juvenile") %>% 
  group_by(sp_name, collection_date) %>% 
  count(lipids) %>% 
  filter(lipids != "uncertain") %>% 
  pivot_wider(id_cols = c("collection_date", "sp_name"), 
              names_from = lipids, 
              values_from = n,
              values_fill = 0) %>% 
  mutate(total = sum(no, yes)) %>% 
  pivot_longer(cols = c(no, yes),
               names_to = "lipids", 
               values_to = "count") %>% 
  mutate(percent = count/total,
         collection_date = lubridate::as_date(collection_date),
         lipids = fct_relevel(lipids, "no", "yes")) %>% 
  ungroup() %>% 
  complete(collection_date, nesting(sp_name, lipids), fill = list(percent = 1)) %>% 
  mutate(percent = if_else(is.na(total) & lipids == "yes", 0, percent)) %>% 
  ggplot(aes(x = collection_date, y = percent, fill = lipids)) + 
  facet_wrap(sp_name~., ncol = 1) + 
  geom_area() + 
  scale_fill_manual(values = lipid_cols) + 
  scale_y_continuous(breaks = c(0,1)) + 
  labs(x = "Collection Date", 
       y = "Proportion", 
       fill = "Lipids\nPresent") + 
  theme_minimal(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.ticks = element_line())

Temperature Variability

Lake Champlain is highly seasonal, with both average temperatures and temperature variability changing throughout the year. These patterns in the experienced thermal environment may drive the observed variation in copepod thermal limits. However, the time period affecting copepod thermal limits is unknown. Depending the on the duration of time considered, there are large changes in the experienced environment, in particular regarding the temperature range and variance. Consider for example three time periods: the day of collection, one week prior to collection, and four weeks prior to collection. While the overall pattern is similar, we can see that, unsurprisingly, considering longer periods of time results in larger ranges and slightly changes the pattern of variance experienced.

## Defining the function to get predictor values for periods of different lengths
get_predictors = function(daily_values, raw_temp, n_days){
  prefix = str_replace_all(xfun::numbers_to_words(n_days), pattern = " ", replacement = "-")
  
  mean_values = daily_values %>% 
    ungroup() %>% 
    mutate(mean_max = slide_vec(.x = max_temp, .f = mean, .before = n_days, .complete = T),
           mean_min = slide_vec(.x = min_temp, .f = mean, .before = n_days, .complete = T),
           mean_range = slide_vec(.x = range_temp, .f = mean, .before = n_days, .complete = T)) %>% 
    select(date, mean_max, mean_min, mean_range) %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))
  
  period_values = raw_temp %>% 
    mutate(mean = slide_index_mean(temp, i = date, before = days(n_days), 
                                   na_rm = T),
           max = slide_index_max(temp, i = date, before = days(n_days), 
                                 na_rm = T),
           min = slide_index_min(temp, i = date, before = days(n_days),
                                 na_rm = T),
           med = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 na_rm = T, .f = median),
           var = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 .f = var),
           range = max - min) %>%  
    select(-temp) %>%  
    distinct() %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))%>% 
    inner_join(mean_values, by = c("date")) %>%  
    drop_na()
  
  return(period_values)
}

Trait Variation

Shown below are the clutch size distributions for the three diaptomiid species, which produce egg sacs that allow for easy quantification of fecundity.

full_data %>%  
  drop_na(fecundity) %>%  
  ggplot(aes(x = fecundity, fill = sp_name_sub)) + 
  facet_wrap(.~sp_name_sub, ncol = 1) + 
  geom_histogram(binwidth = 2) + 
  scale_fill_manual(values = species_cols) + 
  labs(x = "Fecundity (# Eggs)") +
  theme_matt_facets() + 
  theme(legend.position = "none")

One of the main aims of this project is to examine the patterns and processes driving variation in upper thermal limits across these species of copepods.

Variation with temperature

We expect one of the primary drivers of copepod thermal limits to be temperature. The correlation analysis has shown that the copepods are generally (although not always) responding to the recent thermal environment. Shown below are thermal limits, body size, and fecundity values plotted against the temperature at the time of collection. Also shown is warming tolerance, calculated as the difference between upper thermal limit and the collection temperature.

We generally see an increase in thermal limits with increasing collection temperature, a slight decrease in body size, and variable relationships between temperature and fecundity. All species maintained some degree of buffer between environmental temperatures and upper thermal limits, but Epischura and L. minutus approached their upper thermal limits during the warmest collections during the summer.

ctmax_temp = ggplot(full_data, aes(x = collection_temp, y = ctmax, colour = sp_name)) +   
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

size_temp = ggplot(filter(full_data, sex != "juvenile"), aes(x = collection_temp, y = size, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Length (mm)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

wt_temp = ggplot(full_data, aes(x = collection_temp, y = warming_tol, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Warming Tolerance (°C)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")

eggs_temp = ggplot(full_data, aes(x = collection_temp, y = fecundity, colour = sp_name)) + 
  geom_point(size = 3,
             alpha = 0.3) + 
  geom_smooth(method = "lm", linewidth = 3) +
  labs(x = "Collection Temperature (°C)", 
       y = "Fecundity (# Eggs)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(ctmax_temp, size_temp, wt_temp, eggs_temp, 
          common.legend = T, legend = "right")

sp_ctmax_temp = full_data %>% 
  filter(sp_name != "Osphranticum labronectum") %>% 
  mutate(sp_name = as.factor(sp_name),
         sp_name = fct_reorder(sp_name, ctmax, .desc = T)) %>% 
  ggplot(aes(x = collection_temp, y = ctmax, colour = sp_name)) + 
  facet_wrap(sp_name~.) + 
  geom_point(size = 2, alpha = 0.2) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  labs(x = "Collection Temp. (°C)", 
       y = "CTmax (°C)") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")
ggarrange(sample_dates_plot, sp_ctmax_temp, nrow = 1, 
          labels = "AUTO")

Temperature dependence is relatively weak in L. sicilis, especially at cooler temperatures. We will return to this feature later in the report, but for now we will note that there are two size morphs in this species, which appear to respond differently to decreases in temperature. There are significant differences between the morphs and how temperature affects CTmax.

morph_data = full_data %>% 
  filter(sex == "female" & species == "leptodiaptomus_sicilis") %>%  mutate(sp_name = case_when(
    sp_name == "Leptodiaptomus sicilis" & size >= 0.89 ~ "Large",
    sp_name == "Leptodiaptomus sicilis" & size < 0.89 ~ "Small",
    .default = sp_name
  ))


ggplot(morph_data, aes(x = collection_temp, y = ctmax, colour = sp_name)) + 
  geom_point(size = 2, alpha = 0.8) + 
  geom_smooth(method = "lm", se = T, linewidth = 2) + 
  labs(x = "Collection Temp. (°C)", 
       y = "CTmax (°C)") + 
  theme_matt() + 
  theme(legend.position = "none")


morph.model = lm(data = morph_data, 
                 ctmax ~ collection_temp * sp_name)

knitr::kable(car::Anova(morph.model, type = "III", test = "F"))
Sum Sq Df F value Pr(>F)
(Intercept) 11838.75134 1 3930.374601 0.0000000
collection_temp 107.57172 1 35.712986 0.0000000
sp_name 32.96638 1 10.944584 0.0010357
collection_temp:sp_name 15.88294 1 5.273014 0.0222454
Residuals 1060.26547 352 NA NA

#summary(morph.model)

morph.em = emmeans::emtrends(morph.model, "sp_name", var = "collection_temp")

knitr::kable(pairs(morph.em))
contrast estimate SE df t.ratio p.value
Large - Small 0.1530629 0.0666562 352 2.296304 0.0222454

Copepods spent several days in lab during experiments. Shown below are the CTmax residuals (taken from a model of CTmax against collection temperature) plotted against the time spent in lab before measurements were made. Individual regressions are shown for the residuals against days in lab for each collection. We can see clearly that thermal limits are fairly stable over time.

ggplot(ctmax_resids, aes(x = days_in_lab, y = resids, colour = sp_name, group = collection_date)) + 
  facet_wrap(sp_name~.) + 
  geom_point(size = 4, alpha = 0.5) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  #scale_x_continuous(breaks = c(0:5)) + 
  labs(x = "Days in lab", 
       y = "CTmax Residuals") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt_facets() + 
  theme(legend.position = "none")

full.model = lme4::lmer(data = model_data,
                        ctmax ~ sex + temp_cent + size_cent + dev_eggs + lipids + pathogen + 
                          (1 + days_in_lab + temp_cent + size_cent|sp_name))

car::Anova(full.model)
## Analysis of Deviance Table (Type II Wald chisquare tests)
## 
## Response: ctmax
##             Chisq Df Pr(>Chisq)    
## sex       29.9326  2  3.164e-07 ***
## temp_cent 20.6553  1  5.498e-06 ***
## size_cent  1.9223  1     0.1656    
## dev_eggs   7.6246  2     0.0221 *  
## lipids     3.3415  2     0.1881    
## pathogen  41.4778  4  2.140e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

fixed = fixef(full.model)

model_coefs = coefficients(full.model)$`sp_name` %>%  
  rownames_to_column(var = "species") %>% 
  separate(species, into = c("species"), sep = ":") %>% 
  select(species, "intercept" = "(Intercept)", temp_cent, size_cent, days_in_lab)

ggplot(model_coefs, aes(x = intercept, y = temp_cent)) + 
  geom_smooth(method = "lm", colour = "black") +
  geom_point(aes(colour = species),
             size = 6) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Species Intercept", 
       y = "ARR") +
  theme_matt() + 
  theme(legend.position = "right")



arr_combined = synth_arr %>%
  filter(measure == "upper" & mean_lim > 20) %>% 
  select("group" = genus, arr, mean_lim) %>% 
  mutate("dataset" = "synthesis") %>% 
  bind_rows(
    select(model_coefs, "group" = species, 'arr' = temp_cent, 'mean_lim' = intercept)
  ) %>% 
  mutate(dataset = if_else(is.na(dataset), "new data", "synthesis"))


ggplot(arr_combined, aes(x = mean_lim, y = arr)) + 
  geom_smooth(method = "lm", se = F, 
              linewidth = 2, colour = "grey30") + 
  geom_point(data = filter(arr_combined, dataset != "new data"), 
             size = 4, colour = "grey") + 
  geom_point(data = filter(arr_combined, dataset == "new data"),
             aes(colour = group), 
             size = 4) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Thermal Limit", 
       y = "ARR", 
       colour = "Species") +
  theme_matt() + 
  theme(legend.position = "none")

The term “acclimation response ratio” is often used to describe the effect of temperature on thermal limits. The ARR is calculated as the change in thermal limits per degree change in acclimation temperature. For our data, we will estimate ARR as the slope of CTmax against collection temperature. These slopes were taken from a regression of CTmax against collection temperature and body size. Two different model types were used, a simple linear regression and a mixed effects model. The estimated ARR values were generally highly similar between the model types used.

Sex and stage variation in thermal limits

Previous sections have generally lumped juvenile, female, and male individuals together. There may be important stage- or sex-specific differences in CTmax though. For several species, we have measurements for individuals in different stages or of different sexes.

sex_sample_sizes = ctmax_resids %>%  
  group_by(sp_name, sex) %>%  
  summarise(num = n()) %>%  
  pivot_wider(id_cols = sp_name,
              names_from = sex, 
              values_from = num,
              values_fill = 0) %>% 
  select("Species" = sp_name, "Juvenile" = juvenile, "Female" = female, "Male" = male)

knitr::kable(sex_sample_sizes, align = "c")
Species Juvenile Female Male
Epischura lacustris 37 45 20
Leptodiaptomus minutus 12 273 38
Leptodiaptomus sicilis 31 356 95
Limnocalanus macrurus 4 43 39
Osphranticum labronectum 0 1 0
Senecella calanoides 13 21 8
Skistodiaptomus oregonensis 15 231 28

The female-male and female-juvenile comparisons show that there are generally no differences in thermal limits between these groups.

ctmax_resids %>% 
  filter(sp_name %in% filter(sex_sample_sizes, Male > 0, Female > 0)$Species & 
           sex != "juvenile") %>% 
  ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) + 
  facet_wrap(sp_name~., ncol = 2) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  geom_point(size = 3,
             alpha = 0.5,
             position = position_jitter(height = 0, width = 0.05)) +  
  labs(x = "Sex", 
       y = "CTmax Residuals") + 
  scale_colour_manual(values = species_cols) + 
  theme_bw(base_size = 18) + 
  theme(legend.position = "none", 
        panel.grid = element_blank())

ctmax_resids %>% 
  filter(sp_name %in% filter(sex_sample_sizes, Juvenile > 0 & Female > 0)$Species & 
           sex != "male") %>% 
  ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) + 
  facet_wrap(sp_name~., ncol = 2) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  geom_point(size = 3,
             alpha = 0.5,
             position = position_jitter(height = 0, width = 0.05)) +  
  labs(x = "Sex", 
       y = "CTmax (°C)") + 
  scale_colour_manual(values = species_cols) + 
  theme_bw(base_size = 18) + 
  theme(legend.position = "none", 
        panel.grid = element_blank())

Trait Correlations and Trade-offs

A relationship between size and upper thermal limits has been suggested in a wide range of other taxa. Shown below are the measured upper thermal limits plotted against prosome length. The overall relationship (inclusive of all species) is shown as the black line in the background. Regressions for each individual species are also shown. Across the entire assemblage, there is a strong decrease in thermal limits with increasing size.


full_data %>% 
  #filter(sex == "female") %>%  
  ggplot( aes(x = size, y = ctmax, colour = sp_name)) + 
  geom_smooth(data = full_data, 
              aes(x = size, y = ctmax),
              method = "lm", 
              colour ="black", 
              linewidth = 2.5) + 
  geom_point(size = 2, alpha = 0.3) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Shown here is the relationship for each species individually.

full_data %>% 
  #filter(sex == "female") %>%  
  group_by(sp_name) %>% filter(n() >2) %>% filter(!str_detect(sp_name, pattern = "kindti")) %>% 
  ggplot( aes(x = size, y = ctmax, colour = sp_name)) + 
  facet_wrap(sp_name~., scales = "free", nrow = 2) + 
  geom_point(size = 2, alpha = 0.8) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "none")

Shown below is the relationship between mean size and mean thermal limits for females of each species. We see that larger species within the community tend to have a lower thermal limit than smaller species.

full_data %>% 
  group_by(sp_name, sex) %>% 
  summarize(mean_ctmax = mean(ctmax, na.rm = T),
            mean_size = mean(size, na.rm = T)) %>% 
  #filter(sex == "female") %>% 
  ggplot(aes(x = mean_size, y = mean_ctmax)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2, colour = "black") + 
  geom_point(aes(colour = sp_name, shape = sex),
             size = 5) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Shown here is the relationship between fecundity and size, showing the classic pattern of increasing egg production with increasing size.

ctmax_resids %>%  
  drop_na(fecundity) %>% 
  ggplot(aes(x = size, y = fecundity, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 2, alpha = 0.5) + 
  labs(x = "Prosome length (mm)", 
       y = "Fecundity (# Eggs)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Individuals may also allocate energy to different fitness related traits, prioritizing reproductive output over environmental tolerance, for example. Shown below is the relationship between CTmax residuals (again, controlling for the effects of collection temperature) against fecundity. We can see clearly that individuals with increased fecundity are not decreasing thermal limits, suggesting that there is no energetic trade-off between these traits.

ctmax_resids %>%  
  drop_na(fecundity) %>% 
  ggplot(aes(x = resids, y = fecundity_resids, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 2, alpha = 0.5) + 
  labs(x = "CTmax Residuals", 
       y = "Fecundity Residuals",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

Other patterns in variation

Leptodiaptomus sicilis is the most abundant species during the winter. There was a large shift in the size of mature females towards the end of December. These large and small individuals are the same species (confirmed via COI sequencing), suggesting this shift may reflect a transition from one generation to another and that, unlike in many other lakes, there are two generations of L. sicilis per year in Lake Champlain. This size difference may be caused by differences in the developmental environments. For example, individuals developing in January grow up at very low temperatures, and therefore may reach larger sizes. These individuals oversummer in deep waters, then re-emerge in October and produce a new generation. Water temperatures are still fairly high through November, which results in a generation of smaller individuals, which mature in time to produce a new generation in January.

Shown below is the distribution of pairwise distances between COI sequences of large and small morphs. Distances in both within- and across-morph comparisons are small.

ind_dist = ape::dist.dna(sic_dnabin, model = "raw") %>% as.matrix %>% 
  as_tibble() %>%
  mutate("ind1" = colnames(.)) %>% 
  pivot_longer(-ind1, names_to = "ind2", values_to = "dist") %>%
  mutate(ind1 = factor(ind1),
         ind2 = factor(ind2)) %>% 
  filter(!(ind1 == "sore1" | ind2 == "sore1")) %>% 
  mutate(
    ind1 = case_when(
      ind1 == "S1" ~ "small1",
      ind1 == "S3" ~ "small3",
      ind1 == "lsic3" ~ "small4",
      ind1 == "lsic5" ~ "small6",
      ind1 == "lsic9" ~ "small8",
      ind1 == "lsic10" ~ "small9",
      ind1 == "lsic11" ~ "small10",
      ind1 == "L1" ~ "large1",
      ind1 == "L2" ~ "large2",
      ind1 == "L3" ~ "large3",
      ind1 == "lsic1" ~ "large4",
      ind1 == "lsic2" ~ "large5",
      ind1 == "lsic7" ~ "large6",
      ind1 == "lsic8" ~ "large7"),
    ind2 = case_when(
      ind2 == "S1" ~ "small1",
      ind2 == "S3" ~ "small3",
      ind2 == "lsic3" ~ "small4",
      ind2 == "lsic5" ~ "small6",
      ind2 == "lsic9" ~ "small8",
      ind2 == "lsic10" ~ "small9",
      ind2 == "lsic11" ~ "small10",
      ind2 == "L1" ~ "large1",
      ind2 == "L2" ~ "large2",
      ind2 == "L3" ~ "large3",
      ind2 == "lsic1" ~ "large4",
      ind2 == "lsic2" ~ "large5",
      ind2 == "lsic7" ~ "large6",
      ind2 == "lsic8" ~ "large7"),
    'comparison' = case_when(
      str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "large") ~ "within",
      str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "small") ~ "within", 
      str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "small") ~ "across",
      str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "large") ~ "across"
    )) 

ggplot(ind_dist, aes(dist, fill = comparison)) +
  geom_histogram(binwidth = 0.005) + 
  labs(x = "Distance") + 
  theme_matt()

full_data %>%  
  filter(sp_name == "Leptodiaptomus sicilis") %>% 
  filter(sex != "juvenile") %>% 
  group_by(collection_date) %>% 
  mutate(size_center = scale(size, center = T, scale = F)) %>% 
  ggplot(aes(y = factor(collection_date), x = size, fill = collection_temp)) + 
  facet_wrap(sex~.) + 
  geom_density_ridges(bandwidth = 0.04) + 
  geom_vline(xintercept = 0.89) + 
  labs(x = "Size (mm)",
       y = "Date", 
       fill = "Coll. Temp. (°C)") + 
  theme_matt() + 
  theme(legend.position = "right",
        axis.text.y = element_text(size = 12))

full_data %>%  
  filter(sp_name == "Leptodiaptomus minutus") %>% 
  filter(sex != "juvenile") %>% 
  ggplot(aes(y = factor(collection_date), x = size, fill = collection_temp)) + 
  facet_wrap(sex~.) + 
  geom_density_ridges(bandwidth = 0.04) + 
  geom_vline(xintercept = 0.69) + 
  labs(x = "Size (mm)",
       y = "Date", 
       fill = "Coll. Temp. (°C)") + 
  coord_cartesian(xlim = c(0.5,0.9)) + 
  theme_matt() + 
  theme(legend.position = "right",
        axis.text.y = element_text(size = 12))

Distribution Lag Non-Linear Model (DLNM approach)

Distributed lag models examine a response variable, measured at multiple time points, as a function of the lagged occurrence of some predictor variable (response y at time t as a function of preditor x(t-lag). This method utilizes a bi-dimensional dose-lag-response function, which essentially examines not only the dose effect, but the effect of the timing of the dose.

# 
# lag_temps = temp_data %>%
#   group_by(date, hour) %>%
#   summarize("mean_temp" = mean(temp, na.rm = T)) %>%
#   ungroup() %>%
#   mutate(point_num = row_number())
# 
# uniq_days = length(unique(lag_temps$date))
# 
# g = gam(mean_temp ~ s(point_num, bs="cr", k=uniq_days + 10),
#     method = "REML",
#     data = lag_temps)
# 
# points = seq(1, nrow(lag_temps), length.out = length(lag_temps$hour))
# 
# df.res = df.residual(g)
# 
# pred_temps = predict(g, newdata = lag_temps, type = "response", se.fit = TRUE)
# 
# lag_temps = lag_temps %>%
#   mutate(trend_T = pred_temps$fit,
#          trend_se = pred_temps$se.fit,
#          temp_diff = mean_temp - trend_T)
# 
# write.csv(lag_temps, file = "./Output/Data/lag_temps.csv", row.names = F)

dlnm_data = full_data %>%  
  filter(sex == "female") %>% 
  filter(sp_name %in% c(
    "Leptodiaptomus sicilis",
    "Leptodiaptomus minutus",
    "Skistodiaptomus oregonensis"
  )) %>% 
  select(collection_date, collection_temp, sp_name, ctmax) %>% 
  group_by(collection_date, collection_temp, sp_name) %>%  
  summarise(mean_ctmax = mean(ctmax, na.rm = T),
            sample = n())

temp_data %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp)) %>% 
  right_join(dlnm_data, by = join_by("date" == "collection_date")) %>% 
  ggplot(aes(x = mean_temp, y = mean_ctmax)) + 
  facet_wrap(.~sp_name) + 
  geom_smooth(method = "gam") + 
  geom_point() + 
  labs(x = "Mean Daily Temp. (°C)",
       y = "Mean CTmax (°C)") + 
theme_matt_facets() + 
  theme(strip.text.x = element_text(size = 12))


sp_list = unique(dlnm_data$sp_name)

for(lag_species in sp_list){
  
  dlnm_data_sp = dlnm_data %>% 
    filter(sp_name == lag_species)
  
  # We need to estimate a matrix of exposure histories for each observation. This contains the series of exposures at each lag (l) for each of the n observations, constrained between l0 (minimum lag) and L (max lag). 

dates = dlnm_data_sp$collection_date # For each of these dates, make a vector of the past 30 days (including the day of collection). NOTE: Don't use 'unique' dates here since some collections had multiple species

exp_hist_z = data.frame()
exp_hist_trend = data.frame()

for(d in dates){
  
  history = lag_temps %>% 
    filter(date <= d & date > d - 31) %>% 
    arrange(desc(date), desc(hour)) %>% 
    mutate(lag = row_number() - 1) %>% 
    select(lag, mean_temp, temp_diff)
  
  z_vec = scale(history$mean_temp)[,1]
  names(z_vec) = history$lag
  
  trend_vec = history$temp_diff
  names(trend_vec) = history$lag

  exp_hist_z = bind_rows(exp_hist_z, z_vec)
  exp_hist_trend = bind_rows(exp_hist_trend, trend_vec)
  
}

#print(max(exp_hist_trend, na.rm = T))

# The cross-basis function from dlnm will use the class of the x parameter to determine what to do. In our case, we need to provide it with the matrix of exposure histories for reach observation (row) and lag (column). 

cb_temps = crossbasis(exp_hist_trend, lag = c(0,dim(exp_hist_trend)[2]-1), 
                      argvar =list(fun="cr",df=3), 
                      arglag=list(fun="cr",df=3,intercept=T))

#summary(cb_temps)

penalized_mat <- cbPen(cb_temps)

#fitting GAM
lag.gam = gam(data = dlnm_data_sp, 
              mean_ctmax ~ cb_temps + collection_temp, 
              method = "GCV.Cp",
              paraPen=list(cb_temps=penalized_mat))

# summary(lag.gam)
# AIC(lag.gam)

#estimation of exposures effects

#default plots
pred_gam_Zs<-crosspred(cb_temps, lag.gam, 
                       cumul=F, cen=0, ci.level = 0.95,
                       at=seq(-4,4, 0.1))

plot(pred_gam_Zs, "contour")

plot(pred_gam_Zs, border = 2, cumul=F,
      theta=110,phi=20,ltheta=-80)

plot(pred_gam_Zs, "slices", 
     var = c(3,-3), 
     lag = c(1,336), 
     col = 2)

}

if(predict_vuln == F){
  knitr::knit_exit()
}
LS0tCnRpdGxlOiBTZWFzb25hbGl0eSBpbiBMYWtlIENoYW1wbGFpbiBDb3BlcG9kIFRoZXJtYWwgTGltaXRzCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGLCBlY2hvID0gRn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgZ2dwdWJyOjp0aGVtZV9wdWJyKGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IGRhcmtfdGV4dCksCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gbWlkX3RleHQpLAogICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygzLCAwLCAwLCAwKSwgIm1tIikpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygwLCA1LCAwLCAwKSwgIm1tIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5nbGUgPSA5MCksCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9YmFzZV9zaXplICogMC45KSwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAwLjksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZSA9ICJib2xkIiksCiAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDAuMjUsIDAuMjUsIDAuMjUsIDAuMjUsImNtIikKICAgICkKfQoKdGhlbWVfbWF0dF9mYWNldHMgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXJrX3RleHQgPSAiZ3JleTIwIil7CiAgbWlkX3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVsyXQogIGxpZ2h0X3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVszXQogIAogIHRoZW1lX2J3KGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplKSwKICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gZGFya190ZXh0KSwKICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBtaWRfdGV4dCksCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDMsIDAsIDAsIDApLCAibW0iKSksCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDAsIDUsIDAsIDApLCAibW0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IDkwKSwKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT1iYXNlX3NpemUgKiAwLjkpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSwiY20iKQogICAgKQp9CgpzcGVjaWVzX2NvbHMgPSBjKCJMZXB0b2RpYXB0b211cyBtaW51dHVzIiA9ICIjZmZkMDI5IiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyBqdXZlbmlsZSIgPSAiI2UzZDhhZiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMgbWFsZSIgPSAiI2ZmZTg5NiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiID0gIiNEODZGMjkiLAogICAgICAgICAgICAgICAgICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIG1hbGUiID0gIiNFMjhDMDAiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiID0gIiNDNUMzNUEiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMgbWFsZSIgPSAiI2U2ZTZhYSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIGp1dmVuaWxlIiA9ICJwbHVtMSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIG1hbGUiID0gInBsdW0zIiwgCiAgICAgICAgICAgICAgICAgIkVwaXNjaHVyYSBsYWN1c3RyaXMiID0gInBsdW00IiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyIgPSAic2t5Ymx1ZTQiLCAKICAgICAgICAgICAgICAgICAiTGltbm9jYWxhbnVzIG1hY3J1cnVzIG1hbGUiID0gInNreWJsdWUzIiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyBqdXZlbmlsZSIgPSAic2t5Ymx1ZSIsIAogICAgICAgICAgICAgICAgICJTZW5lY2VsbGEgY2FsYW5vaWRlcyIgPSAiZGFya3NlYWdyZWVuMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkgbWFsZSIgPSAibGlnaHRibHVlMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkiID0gImxpZ2h0Ymx1ZTQiLAogICAgICAgICAgICAgICAgICJMZXB0b2RvcmEga2luZHRpIGp1dmVuaWxlIiA9ICJsaWdodGJsdWUiLAogICAgICAgICAgICAgICAgICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iID0gImxpZ2h0Y29yYWwiKQpgYGAKCiMjIENvcGVwb2QgQ29sbGVjdGlvbgoKQ29wZXBvZHMgd2VyZSBjb2xsZWN0ZWQgYXQgYXBwcm94aW1hdGVseSB3ZWVrbHkgaW50ZXJ2YWxzIGZyb20gTGFrZSBDaGFtcGxhaW4gKEJ1cmxpbmd0b24gRmlzaGluZyBQaWVyKS4gUGxhbmt0b24gd2FzIGNvbGxlY3RlZCBmcm9tIHRoZSB0b3AgMyBtZXRlcnMgdXNpbmcgYSAyNTAgdW0gbWVzaCBuZXQuIAoKYGBge3J9CiMgIyBMYWtlIENoYW1wbGFpbiBuZWFyIEJ1cmxpbmd0b24sIFZUCiMgc2l0ZU51bWJlciA9ICIwNDI5NDUwMCIKIyBDaGFtcGxhaW5JbmZvID0gcmVhZE5XSVNzaXRlKHNpdGVOdW1iZXIpCiMgcGFyYW1ldGVyQ2QgPSAiMDAwMTAiCiMgc3RhcnREYXRlID0gIjIwMjMtMDEtMDEiCiMgZW5kRGF0ZSA9ICIyMDI0LTUtMjAiCiMgI3N0YXRDZCA9IGMoIjAwMDAxIiwgIjAwMDAyIiwiMDAwMDMiLCAiMDAwMTEiKSAjIDEgLSBtYXgsIDIgLSBtaW4sIDMgPSBtZWFuCiMgCiMgIyBDb25zdHJ1Y3RzIHRoZSBVUkwgZm9yIHRoZSBkYXRhIHdhbnRlZCB0aGVuIGRvd25sb2FkcyB0aGUgZGF0YQojIHVybCA9IGNvbnN0cnVjdE5XSVNVUkwoc2l0ZU51bWJlcnMgPSBzaXRlTnVtYmVyLCBwYXJhbWV0ZXJDZCA9IHBhcmFtZXRlckNkLAojICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnREYXRlID0gc3RhcnREYXRlLCBlbmREYXRlID0gZW5kRGF0ZSwgc2VydmljZSA9ICJ1diIpCiMgCiMgcmF3X3RlbXBzID0gaW1wb3J0V2F0ZXJNTDEodXJsLCBhc0RhdGVUaW1lID0gVCkgJT4lCiMgICBtdXRhdGUoImRhdGUiID0gYXMuRGF0ZShkYXRlVGltZSksCiMgICAgICAgICAgImhvdXIiID0gaG91cihkYXRlVGltZSkpICU+JQojICAgc2VsZWN0KGRhdGVUaW1lLCB0el9jZCwgZGF0ZSwgaG91ciwgZGVnQyA9IFhfMDAwMTBfMDAwMDApCiMgCiMgdGVtcF9kYXRhID0gIHJhd190ZW1wcyAlPiUKIyAgIHNlbGVjdChkYXRlLCBob3VyLCAidGVtcCIgPSBkZWdDKQojIAojIHdyaXRlLmNzdih0ZW1wX2RhdGEsIGZpbGUgPSAiLi9PdXRwdXQvRGF0YS9jaGFtcGxhaW5fdGVtcHMuY3N2Iiwgcm93Lm5hbWVzID0gRikKYGBgCgpDb2xsZWN0aW9ucyBiZWdhbiBpbiBsYXRlIE1heSAyMDIzLiBTZXZlcmFsIGdhcHMgYXJlIHByZXNlbnQsIGJ1dCBjb2xsZWN0aW9ucyBoYXZlIGNvbnRpbnVlZCBhdCByb3VnaGx5IHdlZWtseSBpbnRlcnZhbHMgc2luY2UgdGhlbi4gQ29wZXBvZHMgZnJvbSBgciBsZW5ndGgodW5pcXVlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKWAgY29sbGVjdGlvbnMgd2VyZSB1c2VkIHRvIG1ha2UgYSB0b3RhbCBvZiBgciBkaW0oZnVsbF9kYXRhKVsxXWAgdGhlcm1hbCBsaW1pdCBtZWFzdXJlbWVudHMuIE92ZXIgdGhpcyB0aW1lIHBlcmlvZCwgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgcmFuZ2VkIGZyb20gYHIgcGFzdGUobWluKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX3RlbXApLCAiIHRvICIsIG1heChmdWxsX2RhdGEkY29sbGVjdGlvbl90ZW1wKSwgc2VwID0gIiIpYMKwQy4gICAgIAoKVGhlcmUgaXMgc3Vic3RhbnRpYWwgdmFyaWF0aW9uIGluIHRoZXJtYWwgbGltaXRzIGFjcm9zcyB0aGUgc3BlY2llcyBjb2xsZWN0ZWQuIFRoZXJlIGlzIGFsc28gc29tZSBkZWdyZWUgb2YgdmFyaWF0aW9uIHdpdGhpbiB0aGUgc3BlY2llcywgd2l0aCB0aGVybWFsIGxpbWl0cyBpbmNyZWFzaW5nIHNsaWdodGx5IGR1cmluZyB0aGUgc3VtbWVyLiAgICAKCmBgYHtyIGN0bWF4LXRpbWVzZXJpZXMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQojIyBEYWlseSB2YWx1ZXMgZm9yIHRoZSBwZXJpb2QgZXhhbWluZWQgYnkgZGF0YXNldApjb2xsZWN0aW9uX2NvbmRpdGlvbnMgPSB0ZW1wX2RhdGEgJT4lCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoInJhbmdlX3RlbXAiID0gbWF4X3RlbXAgLSBtaW5fdGVtcCwKICAgICAgICAgZGF0ZSA9IGFzLkRhdGUoZGF0ZSkpICU+JSAKICB1bmdyb3VwKCkgJT4lICAKICBmaWx0ZXIoZGF0ZSA+PSAobWluKGFzLkRhdGUoZnVsbF9kYXRhJGNvbGxlY3Rpb25fZGF0ZSkpIC0gNykpICU+JSAKICBsZWZ0X2pvaW4odW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSksIGJ5ID0gam9pbl9ieShkYXRlID09IGNvbGxlY3Rpb25fZGF0ZSkpCgojIyBNZWFuIGZlbWFsZSB0aGVybWFsIGxpbWl0cyBmb3IgZWFjaCBzcGVjaWVzLCBncm91cGVkIGJ5IGNvbGxlY3Rpb24Kc3BlY2llc19zdW1tYXJpZXMgPSBmdWxsX2RhdGEgJT4lICAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgInNhbXBsZV9zaXplIiA9IG4oKSwKICAgICAgICAgICAgImN0bWF4X3N0X2VyciIgPSAoc2QoY3RtYXgpIC8gc3FydChzYW1wbGVfc2l6ZSkpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3N0X2VyciIgPSAoc2Qoc2l6ZSkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJzaXplX3ZhciIgPSB2YXIoc2l6ZSkpICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBhcnJhbmdlKGRlc2Moc2FtcGxlX3NpemUpKQoKYWR1bHRfc3VtbWFyaWVzID0gZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgInNhbXBsZV9zaXplIiA9IG4oKSwKICAgICAgICAgICAgImN0bWF4X3N0X2VyciIgPSAoc2QoY3RtYXgpIC8gc3FydChzYW1wbGVfc2l6ZSkpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3N0X2VyciIgPSAoc2Qoc2l6ZSkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJzaXplX3ZhciIgPSB2YXIoc2l6ZSkpICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBhcnJhbmdlKGRlc2Moc2FtcGxlX3NpemUpKQoKCmdncGxvdCgpICsgCiAgZ2VvbV92bGluZShkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSkpLCAKICAgICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5OTAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogICMgZ2VvbV9lcnJvcmJhcihkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsCiAgIyAgICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICMgICAgICAgICAgICAgICAgICAgeW1pbiA9IG1lYW5fY3RtYXggLSBjdG1heF9zdF9lcnIsIHltYXggPSBtZWFuX2N0bWF4ICsgY3RtYXhfc3RfZXJyLAogICMgICAgICAgICAgICAgICAgICAgY29sb3VyID0gc3BfbmFtZSksCiAgIyAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwKICAjICAgICAgICAgICAgICAgd2lkdGggPSA1LCBsaW5ld2lkdGggPSAxKSArCiAgIyBnZW9tX3BvaW50KGRhdGEgPSBhZHVsdF9zdW1tYXJpZXMsIAogICMgICAgICAgICAgICBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IG1lYW5fY3RtYXgsIGNvbG91ciA9IHNwX25hbWUsIHNpemUgPSBzYW1wbGVfc2l6ZSkpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpLAogICAgICAgICAgICAgc2l6ZSA9IDIsIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMSwgaGVpZ2h0ID0gMCkpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRhdGUiLCAKICAgICAgIHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIiwKICAgICAgIHNpemUgPSAiU2FtcGxlIFNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpsYWtlX3RlbXBzID0gZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGxhYnMoeCA9ICJEYXRlIiwgCiAgICAgICB5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIsCiAgICAgICBzaXplID0gIlNhbXBsZSBTaXplIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKClRlbXBlcmF0dXJlcyBvYnNlcnZlZCBhdCB0aGUgdGltZSBvZiBjb2xsZWN0aW9uIGNsb3NlbHkgcmVzZW1ibGVkIHRoZSBtYXhpbXVtIGRhaWx5IHRlbXBlcmF0dXJlIGZyb20gdGhlIHRlbXBlcmF0dXJlIHNlbnNvciBkYXRhLiBNYXhpbXVtIHRlbXBlcmF0dXJlIHdhcyB1c2VkIGFzIGEgcHJveHkgaW5zdGVhZCBvZiBtZWFuIHRlbXBlcmF0dXJlIGFzIGNvbGxlY3Rpb25zIHdlcmUgdXN1YWxseSBtYWRlIGR1cmluZyBhZnRlcm5vb25zIG9yIGVhcmx5IGV2ZW5pbmdzLCBqdXN0IGZvbGxvd2luZyB0aGUgd2FybWVzdCBwYXJ0IG9mIHRoZSBkYXkuIAoKYGBge3IgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodD02fQpjb2xsZWN0aW9uX2NvbmRpdGlvbnMgJT4lIAogIGRyb3BfbmEoY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIGdncGxvdChhZXMoeCA9IG1heF90ZW1wLCB5ID0gY29sbGVjdGlvbl90ZW1wKSkgKyAKICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMSwgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1LDE1LDI1KSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYyg1LDE1LDI1KSkgKyAKICBsYWJzKHggPSAiTWF4LiBUZW1wLiBmcm9tIFNlbnNvciAowrBDKSIsCiAgICAgICB5ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArIAogIHRoZW1lX21hdHQoKQpgYGAKCmBgYHtyIHJvdW5kLXN1bW1hcnktMiwgZmlnLndpZHRoPTExLCBmaWcuaGVpZ2h0PTExLCBpbmNsdWRlID0gRn0KZ2dwbG90KCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAKICAgICAgICAgICAgICAgYyhtYXgoZnVsbF9kYXRhJGNvbGxlY3Rpb25fdGVtcCksCiAgICAgICAgICAgICAgICAgbWluKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX3RlbXApKSwgCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTYwIiwKICAgICAgICAgICAgIGxpbmV3aWR0aCA9IGMoMiwxKSwgCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKyAKICBnZW9tX2JhcihkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSksIAogICAgICAgICAgIGFlcyh4ID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgICBzdGF0ID0gImlkZW50aXR5IiwKICAgICAgICAgICBmaWxsID0gImdyZXkzMCIpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgpLAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjcsIGhlaWdodCA9IDApLAogICAgICAgICAgICAgY29sb3VyID0gImdyZXkzMCIsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKyAKICB5bGltKC0zLCA0MCkgKyAKICBjb29yZF9wb2xhcihzdGFydCA9IDApICsgCiAgdGhlbWVfdm9pZCgpCmBgYAoKClNpemUgYWxzbyB2YXJpZWQsIGJ1dCBwcmltYXJpbHkgYmV0d2VlbiByYXRoZXIgdGhhbiB3aXRoaW4gc3BlY2llcy4gCgpgYGB7ciBzaXplLXRpbWVzZXJpZXMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQpnZ3Bsb3QoKSArIAogIGdlb21fdmxpbmUoZGF0YSA9IHVuaXF1ZShzZWxlY3QoZnVsbF9kYXRhLCBjb2xsZWN0aW9uX2RhdGUpKSwgCiAgICAgICAgICAgICBhZXMoeGludGVyY2VwdCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSksCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTkwIiwKICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBjb2xsZWN0aW9uX2NvbmRpdGlvbnMsIAogICAgICAgICAgICBhZXMoeCA9IGFzLkRhdGUoZGF0ZSksIHkgPSBtZWFuX3RlbXApLAogICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCAKICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICAjIGdlb21fZXJyb3JiYXIoZGF0YSA9IHNwZWNpZXNfc3VtbWFyaWVzLAogICMgICAgICAgICAgICAgICBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgCiAgIyAgICAgICAgICAgICAgICAgICB5bWluID0gbWVhbl9jdG1heCAtIGN0bWF4X3N0X2VyciwgeW1heCA9IG1lYW5fY3RtYXggKyBjdG1heF9zdF9lcnIsCiAgIyAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBzcF9uYW1lKSwKICAjICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLAogICMgICAgICAgICAgICAgICB3aWR0aCA9IDUsIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gYWR1bHRfc3VtbWFyaWVzLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gbWVhbl9zaXplICogNDAsIGNvbG91ciA9IHNwX25hbWUsIHNpemUgPSBzYW1wbGVfc2l6ZSksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSkpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbmFtZSA9ICJUZW1wZXJhdHVyZSIsICMgRmVhdHVyZXMgb2YgdGhlIGZpcnN0IGF4aXMKICAgIHNlYy5heGlzID0gc2VjX2F4aXMofi4vNDAsIG5hbWU9IlByb3NvbWUgTGVuZ3RoIChtbSkiKSwgIyBBZGQgYSBzZWNvbmQgYXhpcyBhbmQgc3BlY2lmeSBpdHMgZmVhdHVyZXMKICAgIGJyZWFrcyA9IGMoMCw1LDEwLDE1LDIwLDI1LDMwKQogICkgKyAKICBsYWJzKHggPSAiRGF0ZSIsIAogICAgICAgeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3IgdHJhaXQtZG95LWZlYXR1cmUsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gNywgaW5jbHVkZSA9IEZ9CiNTaG93biBiZWxvdyBpcyBDVG1heCBhbmQgYm9keSBzaXplIGZvciB0aGUgc3BlY2llcyB3aXRoIHRoZSBtb3N0IGRhdGEgKCpTa2lzdG9kaWFwdG9tdXMqLCAqTC4gbWludXR1cyosICpMLiBzaWNpbGlzKiwgYW5kICpFcGlzY2h1cmEqKSwgcGxvdHRlZCBhZ2FpbnN0IHRoZSBkYXkgb2YgdGhlIHllYXIgZm9yIGVhY2ggc2V4L3N0YWdlIHNlcGFyYXRlbHkuIAoKY3RtYXhfZmVhdHVyZSA9IGZ1bGxfZGF0YSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGMoIlNraXN0b2RpYXB0b211cyBvcmVnb25lbnNpcyIsICJMZXB0b2RpYXB0b211cyBtaW51dHVzIiwgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiLCAiRXBpc2NodXJhIGxhY3VzdHJpcyIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X2dyaWQoc3BfbmFtZX5zZXgpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRheSBvZiB0aGUgWWVhciIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMDAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnNpemVfZmVhdHVyZSA9IGZ1bGxfZGF0YSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGMoIlNraXN0b2RpYXB0b211cyBvcmVnb25lbnNpcyIsICJMZXB0b2RpYXB0b211cyBtaW51dHVzIiwgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiLCAiRXBpc2NodXJhIGxhY3VzdHJpcyIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gc2l6ZSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfZ3JpZChzcF9uYW1lfnNleCkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiRGF5IG9mIHRoZSBZZWFyIiwgCiAgICAgICB5ID0gIlNpemUgKG1tKSIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMDAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCmdnYXJyYW5nZShjdG1heF9mZWF0dXJlLCBzaXplX2ZlYXR1cmUsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAibm9uZSIpCmBgYAoKYGBge3Igc3Atb2NjdXJlbmNlcywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0Kc2FtcGxlX2RhdGVzX3Bsb3QgPSBmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc3BfbmFtZSAhPSAiT3NwaHJhbnRpY3VtIGxhYnJvbmVjdHVtIikgJT4lIAogIG11dGF0ZShzcF9uYW1lID0gYXMuZmFjdG9yKHNwX25hbWUpLAogICAgICAgICBzcF9uYW1lID0gZmN0X3Jlb3JkZXIoc3BfbmFtZSwgY3RtYXgpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksIAogICAgICAgICAgICAgeSA9IHNwX25hbWUsIGZpbGwgPSBzcF9uYW1lKSkgKyAKICAjIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGFzX2RhdGUoCiAgIyAgIGMoIjIwMjMtMDUtMDEiLAogICMgICAgICIyMDIzLTA5LTAxIiwKICAjICAgICAiMjAyNC0wMS0wMSIsCiAgIyAgICAgIjIwMjQtMDUtMDEiKSksCiAgIyAgIGNvbG91ciA9ICJncmV5IiwKICAjICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGJhbmR3aWR0aCA9IDMwLAogICAgICAgICAgICAgICAgICAgICAgaml0dGVyZWRfcG9pbnRzID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICBwb2ludF9zaGFwZSA9IDIxLAogICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDEsCiAgICAgICAgICAgICAgICAgICAgICBwb2ludF9jb2xvdXIgPSAiZ3JleTMwIiwKICAgICAgICAgICAgICAgICAgICAgIHBvaW50X2FscGhhID0gMC42LAogICAgICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjksCiAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3BvaW50c19qaXR0ZXIoCiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IDAuMSwgd2lkdGggPSAwKSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjMgbW9udGhzIiwKICAgICAgICAgICAgICAgZGF0ZV9sYWJlbHMgPSAiJWIiKSArIAogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gbHVicmlkYXRlOjphc19kYXRlKGMoIjIwMjMtMDQtMjUiLCAiMjAyNC0wNi0wMSIpKSkgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgI3RoZW1lX3JpZGdlcyhncmlkID0gVCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKClRoZSBzYW1wbGVzIGNhcHR1cmVkIHRoZSBicm9hZCBzZWFzb25hbCBjaGFuZ2VzIGluIGNhbGFub2lkIGNvcGVwb2QgY29tbXVuaXR5IGNvbXBvc2l0aW9uIGluIHRoZSBsYWtlLiBXZSBub3RlLCBob3dldmVyLCB0aGF0IHJhcmUgc3BlY2llcyAoZS5nLiAqU2VuZWNlbGxhKiBhbmQgKkxpbW5vY2FsYW51cyopIHdlcmUgb2Z0ZW4gcHJlZmVyZW50aWFsbHkgc2FtcGxlZCwgc28gYXJlIG92ZXItcmVwcmVzZW50ZWQgaW4gdGhlIGRhdGEgc2V0LiAKCmBgYHtyIHNwLXByb3BzLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDV9CmFkdWx0X3N1bW1hcmllcyAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUoY29sbGVjdGlvbl9udW0gPSBhcy5udW1lcmljKGZhY3Rvcihjb2xsZWN0aW9uX2RhdGUpKSkgJT4lIAogIGdyb3VwX2J5KGNvbGxlY3Rpb25fZGF0ZSkgJT4lICAKICBhcnJhbmdlKGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIHNlbGVjdChzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fbnVtLCBzYW1wbGVfc2l6ZSkgJT4lIAogIG11dGF0ZShzYW1wbGVfc2l6ZSA9IHJlcGxhY2VfbmEoc2FtcGxlX3NpemUsIDApKSAlPiUgCiAgbXV0YXRlKHRvdGFsID0gc3VtKHNhbXBsZV9zaXplKSwKICAgICAgICAgcGVyY2VudGFnZSA9IHNhbXBsZV9zaXplIC8gdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl9kYXRlLCB5ID0gcGVyY2VudGFnZSwgZmlsbCA9IHNwX25hbWUpKSArIAogIGdlb21fYXJlYSgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMSkpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gRGF0ZSIsIAogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwgCiAgICAgICBmaWxsID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCmBgYAoKVGhyb3VnaG91dCB0aGUgc2Vhc29uLCB0aGUgcHJldmFsZW5jZSBvZiB2YXJpb3VzIHVuaWRlbnRpZmllZCBwYXRob2dlbnMgYWxzbyB2YXJpZWQsIHdpdGggdmVyeSBsaXR0bGUgaW5mZWN0aW9uIG9ic2VydmVkIGR1cmluZyB0aGUgV2ludGVyIGFuZCBTcHJpbmcuIAoKYGBge3IgcGF0aG9nZW4tcHJvcHN9CnBhdGhvZ2VuX2NvbHMgPSBjKCJubyIgPSAiZ3JleTk1IiwgImNsb3VkeSIgPSAiaG9uZXlkZXczIiwgInNwb3QiID0gImFudGlxdWV3aGl0ZTMiLCAib3RoZXIiID0gInRvbWF0bzMiKQoKZnVsbF9kYXRhICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkZXZfZWdncywgcGF0aG9nZW4sIGxpcGlkcywgc3BfbmFtZSwgc2V4KSAlPiUgCiAgZ3JvdXBfYnkoKSAlPiUgCiAgZmlsdGVyKHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ3JvdXBfYnkoY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgY291bnQocGF0aG9nZW4pICU+JSAKICBmaWx0ZXIocGF0aG9nZW4gIT0gInVuY2VydGFpbiIpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gImNvbGxlY3Rpb25fZGF0ZSIsIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBwYXRob2dlbiwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBuLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShubywgY2xvdWR5LCBzcG90LCBvdGhlcikpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMobm8sIGNsb3VkeSwgc3BvdCwgb3RoZXIpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXRob2dlbiIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC90b3RhbCwKICAgICAgICAgY29sbGVjdGlvbl9kYXRlID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksCiAgICAgICAgIHBhdGhvZ2VuID0gZmN0X3JlbGV2ZWwocGF0aG9nZW4sICJubyIsICJjbG91ZHkiLCAic3BvdCIsICJvdGhlciIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl9kYXRlLCB5ID0gcGVyY2VudCwgZmlsbCA9IHBhdGhvZ2VuKSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhdGhvZ2VuX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiUGF0aG9nZW4iKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCmBgYAoKVGhlIHRyYW5zcGFyZW50IGJvZGllcyBvZiB0aGVzZSBjb3BlcG9kcyBhbHNvIGFsbG93ZWQgdXMgdG8gZXhhbWluZSBzZWFzb25hbCBwYXR0ZXJucyBpbiBsaXBpZCByZXNlcnZlcyBhbmQgaW4gdGhlIHByb2R1Y3Rpb24gb2YgZWdncy4gTWF0dXJpbmcgb29jeXRlcyBhcmUgdmlzaWJsZSBpbiBmZW1hbGUgY29wZXBvZHMgYmVmb3JlIHRoZXkgYXJlIHJlbGVhc2VkLiBUaGVyZSB3YXMgbm8gc3Ryb25nIHNlYXNvbmFsIGN5Y2xlIGluIHRoZSBwcm9kdWN0aW9uIG9mIHRoZXNlIGVnZ3MgaW4gYW55IHNwZWNpZXMsIGFuZCBpbnN0ZWFkLCBmZW1hbGVzIHdlcmUgcmVwcm9kdWN0aXZlbHkgYWN0aXZlIHRocm91Z2hvdXQgdGhlaXIgcmVzcGVjdGl2ZSBzZWFzb25zIG9mIG9jY3VyZW5jZS4gCgpgYGB7ciBkZXZlZ2dzLXByb3BzLCBmaWcuaGVpZ2h0ID0gMTIsIGZpZy53aWR0aCA9IDh9CmRldl9lZ2dzX2NvbHMgPSBjKCJubyIgPSAiZ3JleTk1IiwgInllcyIgPSAibGlnaHRibHVlMyIpCgpmdWxsX2RhdGEgJT4lIAogIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIGRldl9lZ2dzLCBwYXRob2dlbiwgbGlwaWRzLCBzcF9uYW1lLCBzZXgpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgY291bnQoZGV2X2VnZ3MpICU+JSAKICBmaWx0ZXIoZGV2X2VnZ3MgIT0gInVuY2VydGFpbiIpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYygiY29sbGVjdGlvbl9kYXRlIiwgInNwX25hbWUiKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IGRldl9lZ2dzLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG4sCiAgICAgICAgICAgICAgdmFsdWVzX2ZpbGwgPSAwKSAlPiUgCiAgbXV0YXRlKHRvdGFsID0gc3VtKG5vLCB5ZXMpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKG5vLCB5ZXMpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJkZXZfZWdncyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC90b3RhbCwKICAgICAgICAgY29sbGVjdGlvbl9kYXRlID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksCiAgICAgICAgIGRldl9lZ2dzID0gZmN0X3JlbGV2ZWwoZGV2X2VnZ3MsICJubyIsICJ5ZXMiKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgY29tcGxldGUoY29sbGVjdGlvbl9kYXRlLCBuZXN0aW5nKHNwX25hbWUsIGRldl9lZ2dzKSwgZmlsbCA9IGxpc3QocGVyY2VudCA9IDEpKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBpZl9lbHNlKGlzLm5hKHRvdGFsKSAmIGRldl9lZ2dzID09ICJ5ZXMiLCAwLCBwZXJjZW50KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBkZXZfZWdncykpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIG5jb2wgPSAxKSArIAogIGdlb21fYXJlYSgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZGV2X2VnZ3NfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLDEpKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIERhdGUiLCAKICAgICAgIHkgPSAiUHJvcG9ydGlvbiIsIAogICAgICAgZmlsbCA9ICJEZXZlbG9waW5nIFxuRWdncyIpICsgCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoKSkKYGBgCgpUaGUgcHJlc2VuY2Ugb2YgbGlwaWRzIHZhcmllZCBhY3Jvc3Mgc3BlY2llcywgd2l0aCBvbmx5ICpMLiBtaW51dHVzKiwgKkwuIHNpY2lsaXMqLCBhbmQgKkxpbW5vY2FsYW51cyogcmVndWxhcmx5IHBvc3Nlc3NpbmcgbGlwaWQgc3RvcmVzLiAKCmBgYHtyIGxpcGlkcy1wcm9wcywgZmlnLmhlaWdodCA9IDEyLCBmaWcud2lkdGggPSA4fQpsaXBpZF9jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJ5ZXMiID0gInNpZW5uYTIiKQoKZnVsbF9kYXRhICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkZXZfZWdncywgcGF0aG9nZW4sIGxpcGlkcywgc3BfbmFtZSwgc2V4KSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KGxpcGlkcykgJT4lIAogIGZpbHRlcihsaXBpZHMgIT0gInVuY2VydGFpbiIpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYygiY29sbGVjdGlvbl9kYXRlIiwgInNwX25hbWUiKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IGxpcGlkcywgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBuLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShubywgeWVzKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhubywgeWVzKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAibGlwaWRzIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJjb3VudCIpICU+JSAKICBtdXRhdGUocGVyY2VudCA9IGNvdW50L3RvdGFsLAogICAgICAgICBjb2xsZWN0aW9uX2RhdGUgPSBsdWJyaWRhdGU6OmFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSwKICAgICAgICAgbGlwaWRzID0gZmN0X3JlbGV2ZWwobGlwaWRzLCAibm8iLCAieWVzIikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKGNvbGxlY3Rpb25fZGF0ZSwgbmVzdGluZyhzcF9uYW1lLCBsaXBpZHMpLCBmaWxsID0gbGlzdChwZXJjZW50ID0gMSkpICU+JSAKICBtdXRhdGUocGVyY2VudCA9IGlmX2Vsc2UoaXMubmEodG90YWwpICYgbGlwaWRzID09ICJ5ZXMiLCAwLCBwZXJjZW50KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBsaXBpZHMpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGxpcGlkX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiTGlwaWRzXG5QcmVzZW50IikgKyAKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZSgpKQpgYGAKCgojIyBUZW1wZXJhdHVyZSBWYXJpYWJpbGl0eQpMYWtlIENoYW1wbGFpbiBpcyBoaWdobHkgc2Vhc29uYWwsIHdpdGggYm90aCBhdmVyYWdlIHRlbXBlcmF0dXJlcyBhbmQgdGVtcGVyYXR1cmUgdmFyaWFiaWxpdHkgY2hhbmdpbmcgdGhyb3VnaG91dCB0aGUgeWVhci4gVGhlc2UgcGF0dGVybnMgaW4gdGhlIGV4cGVyaWVuY2VkIHRoZXJtYWwgZW52aXJvbm1lbnQgbWF5IGRyaXZlIHRoZSBvYnNlcnZlZCB2YXJpYXRpb24gaW4gY29wZXBvZCB0aGVybWFsIGxpbWl0cy4gSG93ZXZlciwgdGhlIHRpbWUgcGVyaW9kIGFmZmVjdGluZyBjb3BlcG9kIHRoZXJtYWwgbGltaXRzIGlzIHVua25vd24uIERlcGVuZGluZyB0aGUgb24gdGhlIGR1cmF0aW9uIG9mIHRpbWUgY29uc2lkZXJlZCwgdGhlcmUgYXJlIGxhcmdlIGNoYW5nZXMgaW4gdGhlIGV4cGVyaWVuY2VkIGVudmlyb25tZW50LCBpbiBwYXJ0aWN1bGFyIHJlZ2FyZGluZyB0aGUgdGVtcGVyYXR1cmUgcmFuZ2UgYW5kIHZhcmlhbmNlLiBDb25zaWRlciBmb3IgZXhhbXBsZSB0aHJlZSB0aW1lIHBlcmlvZHM6IHRoZSBkYXkgb2YgY29sbGVjdGlvbiwgb25lIHdlZWsgcHJpb3IgdG8gY29sbGVjdGlvbiwgYW5kIGZvdXIgd2Vla3MgcHJpb3IgdG8gY29sbGVjdGlvbi4gV2hpbGUgdGhlIG92ZXJhbGwgcGF0dGVybiBpcyBzaW1pbGFyLCB3ZSBjYW4gc2VlIHRoYXQsIHVuc3VycHJpc2luZ2x5LCBjb25zaWRlcmluZyBsb25nZXIgcGVyaW9kcyBvZiB0aW1lIHJlc3VsdHMgaW4gbGFyZ2VyIHJhbmdlcyBhbmQgc2xpZ2h0bHkgY2hhbmdlcyB0aGUgcGF0dGVybiBvZiB2YXJpYW5jZSBleHBlcmllbmNlZC4gCgpgYGB7ciBkYWlseS10ZW1wLWRhdGEsIGluY2x1ZGUgPSBGfQojIyBEYWlseSB2YWx1ZXMKZGFpbHlfdGVtcF9kYXRhID0gdGVtcF9kYXRhICU+JQogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RlbXAgPSBtZWFuKHRlbXApLAogICAgICAgICAgICBtZWRfdGVtcCA9IG1lZGlhbih0ZW1wKSwKICAgICAgICAgICAgdmFyX3RlbXAgPSB2YXIodGVtcCksIAogICAgICAgICAgICBtaW5fdGVtcCA9IG1pbih0ZW1wKSwgCiAgICAgICAgICAgIG1heF90ZW1wID0gbWF4KHRlbXApKSAlPiUgCiAgbXV0YXRlKCJyYW5nZV90ZW1wIiA9IG1heF90ZW1wIC0gbWluX3RlbXApCgpkYXlfcHJpb3JfdGVtcF9kYXRhID0gdGVtcF9kYXRhICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSwKICAgICAgICAgICAgbWVkX3RlbXAgPSBtZWRpYW4odGVtcCksCiAgICAgICAgICAgIHZhcl90ZW1wID0gdmFyKHRlbXApLCAKICAgICAgICAgICAgbWluX3RlbXAgPSBtaW4odGVtcCksIAogICAgICAgICAgICBtYXhfdGVtcCA9IG1heCh0ZW1wKSkgJT4lIAogIG11dGF0ZShkYXRlID0gZGF0ZSArIDEpICU+JSAKICByZW5hbWVfd2l0aCguZm4gPSB+IHBhc3RlMCgicHJpb3JfZGF5XyIsIC54KSwgLmNvbHMgPSBjKC1kYXRlKSkKCmRhaWx5X3Bsb3QgPSBkYWlseV90ZW1wX2RhdGEgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInBhcmFtZXRlciIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKICAgICJtZWRfdGVtcCIgPSAic2VhZ3JlZW4zIiwKICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAogICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKICAgICJyYW5nZV90ZW1wIiA9ICJnb2xkZW5yb2QzIiwKICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiAgKSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMuRGF0ZShjKCIyMDIzLTAxLTAxIiwgIjIwMjMtMDQtMDEiLCAiMjAyMy0wNy0wMSIpKSkgKyAKICBnZ3RpdGxlKCJEYWlseSBWYWx1ZXMiKSArIAogIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiAgICAgICB4ID0gIiIpICsgCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCmBgYAoKYGBge3IgcHJlZGljdG9ycy1mdW5jdGlvbn0KIyMgRGVmaW5pbmcgdGhlIGZ1bmN0aW9uIHRvIGdldCBwcmVkaWN0b3IgdmFsdWVzIGZvciBwZXJpb2RzIG9mIGRpZmZlcmVudCBsZW5ndGhzCmdldF9wcmVkaWN0b3JzID0gZnVuY3Rpb24oZGFpbHlfdmFsdWVzLCByYXdfdGVtcCwgbl9kYXlzKXsKICBwcmVmaXggPSBzdHJfcmVwbGFjZV9hbGwoeGZ1bjo6bnVtYmVyc190b193b3JkcyhuX2RheXMpLCBwYXR0ZXJuID0gIiAiLCByZXBsYWNlbWVudCA9ICItIikKICAKICBtZWFuX3ZhbHVlcyA9IGRhaWx5X3ZhbHVlcyAlPiUgCiAgICB1bmdyb3VwKCkgJT4lIAogICAgbXV0YXRlKG1lYW5fbWF4ID0gc2xpZGVfdmVjKC54ID0gbWF4X3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCksCiAgICAgICAgICAgbWVhbl9taW4gPSBzbGlkZV92ZWMoLnggPSBtaW5fdGVtcCwgLmYgPSBtZWFuLCAuYmVmb3JlID0gbl9kYXlzLCAuY29tcGxldGUgPSBUKSwKICAgICAgICAgICBtZWFuX3JhbmdlID0gc2xpZGVfdmVjKC54ID0gcmFuZ2VfdGVtcCwgLmYgPSBtZWFuLCAuYmVmb3JlID0gbl9kYXlzLCAuY29tcGxldGUgPSBUKSkgJT4lIAogICAgc2VsZWN0KGRhdGUsIG1lYW5fbWF4LCBtZWFuX21pbiwgbWVhbl9yYW5nZSkgJT4lIAogICAgcmVuYW1lX3dpdGgoIH4gcGFzdGUocHJlZml4LCAiZGF5IiwgLngsIHNlcCA9ICJfIiksIC5jb2xzID0gYygtZGF0ZSkpCiAgCiAgcGVyaW9kX3ZhbHVlcyA9IHJhd190ZW1wICU+JSAKICAgIG11dGF0ZShtZWFuID0gc2xpZGVfaW5kZXhfbWVhbih0ZW1wLCBpID0gZGF0ZSwgYmVmb3JlID0gZGF5cyhuX2RheXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYV9ybSA9IFQpLAogICAgICAgICAgIG1heCA9IHNsaWRlX2luZGV4X21heCh0ZW1wLCBpID0gZGF0ZSwgYmVmb3JlID0gZGF5cyhuX2RheXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFfcm0gPSBUKSwKICAgICAgICAgICBtaW4gPSBzbGlkZV9pbmRleF9taW4odGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFfcm0gPSBUKSwKICAgICAgICAgICBtZWQgPSBzbGlkZV9pbmRleF9kYmwodGVtcCwgLmkgPSBkYXRlLCAuYmVmb3JlID0gZGF5cyhuX2RheXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFfcm0gPSBULCAuZiA9IG1lZGlhbiksCiAgICAgICAgICAgdmFyID0gc2xpZGVfaW5kZXhfZGJsKHRlbXAsIC5pID0gZGF0ZSwgLmJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5mID0gdmFyKSwKICAgICAgICAgICByYW5nZSA9IG1heCAtIG1pbikgJT4lICAKICAgIHNlbGVjdCgtdGVtcCkgJT4lICAKICAgIGRpc3RpbmN0KCkgJT4lIAogICAgcmVuYW1lX3dpdGgoIH4gcGFzdGUocHJlZml4LCAiZGF5IiwgLngsIHNlcCA9ICJfIiksIC5jb2xzID0gYygtZGF0ZSkpJT4lIAogICAgaW5uZXJfam9pbihtZWFuX3ZhbHVlcywgYnkgPSBjKCJkYXRlIikpICU+JSAgCiAgICBkcm9wX25hKCkKICAKICByZXR1cm4ocGVyaW9kX3ZhbHVlcykKfQpgYGAKCmBgYHtyIHByZWRpY3RvcnMtYW5kLXBsb3RzLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NSwgaW5jbHVkZSA9IEZ9CiMgIyMgR2V0dGluZyBwcmVkaWN0b3IgdmFyaWFibGVzIGZvciBkaWZmZXJlbnQgcGVyaW9kcwojIAojICMjIyBTaG9ydCAodGhyZWUgZGF5cykKIyB0aHJlZV9kYXlfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAzKQojIAojICMjIyBPTkUgV0VFSwp3ZWVrX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSA3KQoKd2Vla19wbG90ID0gd2Vla190ZW1wcyAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JQogIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJzZXZlbl9kYXlfbWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9tZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfbWF4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X21pbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV92YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfcmFuZ2UiKSkgJT4lCiAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JQogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKICAgICJtZWRfdGVtcCIgPSAic2VhZ3JlZW4zIiwKICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMuRGF0ZShjKCIyMDIzLTAxLTAxIiwgIjIwMjMtMDQtMDEiLCAiMjAyMy0wNy0wMSIpKSkgKwogIGdndGl0bGUoIk9uZSBXZWVrIikgKwogIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBUV08gV0VFS1MKIyB0d29fd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAxNCkKIyAKIyB0d29fd2Vla19wbG90ID0gdHdvX3dlZWtfdGVtcHMgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKIyAgIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJmb3VydGVlbl9kYXlfbWVhbiIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X21lZCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X21heCIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV9taW4iLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfdmFyIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfcmFuZ2UiKSkgJT4lIAojICAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArIAojICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiMgICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAojICAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiMgICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAojICAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAojICAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiMgICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiMgICApKSArIAojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiMgICBnZ3RpdGxlKCJUd28gV2Vla3MiKSArIAojICAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKIyAgICAgICAgeCA9ICIiKSArIAojICAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsgCiMgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBGT1VSIFdFRUtTCmZvdXJfd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IDI4KQoKZm91cl93ZWVrX3Bsb3QgPSBmb3VyX3dlZWtfdGVtcHMgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUKICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygidHdlbnR5LWVpZ2h0X2RheV9tZWFuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9tZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X21heCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfbWluIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV92YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X3JhbmdlIikpICU+JQogIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsCiAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAogICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAogICAgInZhcl90ZW1wIiA9ICJkYXJrZ29sZGVucm9kMSIKICApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsKICBnZ3RpdGxlKCJGb3VyIFdlZWtzIikgKwogIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIAojIAojICMjIyBFSUdIVCBXRUVLUwojIGVpZ2h0X3dlZWtfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IDU2KQojIAojIGVpZ2h0X3dlZWtfcGxvdCA9IGVpZ2h0X3dlZWtfdGVtcHMgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKIyAgIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJmaWZ0eS1zaXhfZGF5X21lYW4iLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWVkIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21heCIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWluIiwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlmdHktc2l4X2RheV92YXIiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfcmFuZ2UiKSkgJT4lIAojICAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArIAojICAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiMgICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAojICAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiMgICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAojICAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAojICAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiMgICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiMgICApKSArIAojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiMgICBnZ3RpdGxlKCJFaWdodCBXZWVrcyIpICsgCiMgICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAojICAgICAgICB4ID0gIiIpICsgCiMgICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKyAKIyAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCiMgCmdnYXJyYW5nZShkYWlseV9wbG90LCB3ZWVrX3Bsb3QsIGZvdXJfd2Vla19wbG90LCAKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBULCBucm93ID0gMSwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKYGBge3IsIGluY2x1ZGUgPSBGfQojVGhlIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMgZXhhbWluZWQgYnkgdGhpcyBjbGltYXRlIGRhdGEgaGlnaGxpZ2h0cyB0aGF0IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtaW5pbXVtIGFuZCBtYXhpbXVtIHRlbXBlcmF0dXJlcyBjaGFuZ2VzIGJhc2VkIG9uIHRoZSB3aW5kb3cgZXhhbWluZWQuIEZvciBleGFtcGxlLCBtaW5pbXVtIGFuZCBtYXhpbXVtIHRlbXBlcmF0dXJlcyBleHBlcmllbmNlZCBvdmVyIHdlZWtseSBpbnRlcnZhbHMgYXJlIGNsb3NlbHkgbGlua2VkLCB3aGVyZWFzIHRoZXJlIGlzIGEgZGlzdGluY3Qgc2Vhc29uYWwgY3ljbGUgaW4gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1pbmltdW0gYW5kIG1heGltdW0gdGVtcGVyYXR1cmVzIGV4cGVyaWVuY2VkIG92ZXIgcGVyaW9kcyBvZiBmb3VyIHdlZWtzLiAKCm9uZV93ZWVrX2RveV9kYXRhID0gd2Vla190ZW1wcyAlPiUgCiAgbXV0YXRlKGRveSA9IHlkYXkoZGF0ZSkpCgpvbmVfd2Vla190ZW1wX2NpcmNsZSA9IGdncGxvdChvbmVfd2Vla19kb3lfZGF0YSwgYWVzKHggPSBzZXZlbl9kYXlfbWVhbl9tYXgsIHkgPSBzZXZlbl9kYXlfbWVhbl9taW4sIGNvbG91ciA9IGRveSkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50MigKICAgIGhpZ2ggPSAiZG9kZ2VyYmx1ZTQiLAogICAgbWlkID0gImNvcmFsMiIsCiAgICBsb3cgPSAiZG9kZ2VyYmx1ZTQiLAogICAgbWlkcG9pbnQgPSAxODIuNSkgKyAKICBsYWJzKHggPSAiTWF4LiBUZW1wLiAowrBDKSIsCiAgICAgICB5ID0gIk1pbi4gVGVtcC4gKMKwQykiKSArIAogIGxhYnMoeCA9ICJNYXguIFRlbXAuICjCsEMpIiwKICAgICAgIHkgPSAiTWluLiBUZW1wLiAowrBDKSIpICsgCiAgZ2d0aXRsZSgiT25lIFdlZWsiKSArIAogIHRoZW1lX21hdHQoKQoKZm91cl93ZWVrX2RveV9kYXRhID0gZm91cl93ZWVrX3RlbXBzICU+JSAKICBtdXRhdGUoZG95ID0geWRheShkYXRlKSkKCmZvdXJfd2Vla190ZW1wX2NpcmNsZSA9IGdncGxvdChmb3VyX3dlZWtfZG95X2RhdGEsIGFlcyh4ID0gYHR3ZW50eS1laWdodF9kYXlfbWF4YCwgeSA9IGB0d2VudHktZWlnaHRfZGF5X21pbmAsIGNvbG91ciA9IGRveSkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50MigKICAgIGhpZ2ggPSAiZG9kZ2VyYmx1ZTQiLAogICAgbWlkID0gImNvcmFsMiIsCiAgICBsb3cgPSAiZG9kZ2VyYmx1ZTQiLAogICAgbWlkcG9pbnQgPSAxODIuNSkgKyAKICBsYWJzKHggPSAiTWF4LiBUZW1wLiAowrBDKSIsCiAgICAgICB5ID0gIk1pbi4gVGVtcC4gKMKwQykiKSArIAogIGdndGl0bGUoIkZvdXIgV2VlayIpICsgCiAgdGhlbWVfbWF0dCgpCgpnZ2FycmFuZ2Uob25lX3dlZWtfdGVtcF9jaXJjbGUsIGZvdXJfd2Vla190ZW1wX2NpcmNsZSwKICAgICAgICAgIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAiYm90dG9tIikKYGBgCgpgYGB7ciwgaW5jbHVkZSA9IEZ9CiNUaGUgdGhlcm1hbCBlbnZpcm9ubWVudCBvdmVyIGFueSBwZXJpb2Qgb2YgdGltZSBtYXkgZHJpdmUgcGF0dGVybnMgaW4gdGhlcm1hbCBhY2NsaW1hdGlvbi4gVG8gZXhwbG9yZSB0aGUgcG90ZW50aWFsIGVmZmVjdHMgb2YgZGlmZmVyZW50IGFjY2xpbWF0aW9uIHdpbmRvd3MsIHdlIGV4YW1pbmVkIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZXJtYWwgbGltaXRzIGFuZCBkaWZmZXJlbnQgcmVwcmVzZW50YXRpb25zIG9mIHRoZSB0aGVybWFsIGVudmlyb25tZW50IGZvciBkaWZmZXJlbnQgcGVyaW9kcyBvZiB0aW1lLiBTaG93biBiZWxvdyBhcmUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBmb3IgdGhlc2UgcmVsYXRpb25zaGlwcy4gRWFjaCBmYWNldCBzaG93cyB0aGUgcmVsYXRpb25zaGlwIGZvciBhIGRpZmZlcmVudCBkaW1lbnNpb24gb2YgdGhlIHRoZXJtYWwgZW52aXJvbm1lbnQuIENvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBhcmUgcGxvdHRlZCBmb3IgZGlmZmVyZW50IGR1cmF0aW9ucywgZm9yIHNwZWNpZXMgdGhhdCB3ZXJlIGNvbGxlY3RlZCBtb3JlIHRoYW4gZml2ZSB0aW1lcy4gT25seSBkYXRhIGZvciBtYXR1cmUgZmVtYWxlIGNvcGVwb2RzIHdhcyBpbmNsdWRlZC4gCgojV2UgY2FuIHNlZSB0aGF0LCBpbiBnZW5lcmFsLCBjb3BlcG9kcyBhcmUgcmVzcG9uZGluZyB0byBwcm94aW1hdGUgY3VlcyBmcm9tIHRoZSB0aGVybWFsIGVudmlyb25tZW50LCB3aXRoIGNvcnJlbGF0aW9ucyBnZW5lcmFsbHkgZHJvcHBpbmcgb2ZmIHN1YnN0YW50aWFsbHkgYXMgYWNjbGltYXRpb24gd2luZG93IGR1cmF0aW9uIGluY3JlYXNlcy4gQW4gZXhjZXB0aW9uIGlzICpFcGlzY2h1cmEgbGFjdXN0cmlzKiwgd2hpY2ggYXBwZWFycyB0byBiZSByZXNwb25kaW5nIHRvIG1heGltdW0gdGVtcGVyYXR1cmVzIGV4cGVyaWVuY2VkIG92ZXIgYSAyMCBkYXkgdGltZSBwZXJpb2QuIAoKIyMjIFB1bGxpbmcgcHJlZGljdG9ycyBhbmQgbWVhc3VyaW5nIGNvcnJlbGF0aW9ucyBmb3IgbXVjaCBmaW5lciB0aW1lc2NhbGVzOyAxLTU2IGRheXMKCm51bV9jb2xscyA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIHNlbGVjdChjb2xsZWN0aW9uX2RhdGUsIHNwX25hbWUpICU+JSAgCiAgZGlzdGluY3QoKSAlPiUgIAogIGNvdW50KHNwX25hbWUpICU+JSAKICBmaWx0ZXIobiA+PSA1KQoKY29ycl92YWxzID0gZGF0YS5mcmFtZSgpCgpkdXJfdmFscyA9IGMoMTo1MCkKZm9yKGkgaW4gZHVyX3ZhbHMpewogIAogIGR1cmF0aW9uX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IGkpICU+JSAKICAgIGZpbHRlcihkYXRlICVpbiUgYXNfZGF0ZSh1bmlxdWUoZnVsbF9kYXRhJGNvbGxlY3Rpb25fZGF0ZSkpKQogIAogIGNvcnJfZGF0YSA9IGZ1bGxfZGF0YSAlPiUKICAgIGZpbHRlcihzcF9uYW1lICVpbiUgbnVtX2NvbGxzJHNwX25hbWUpICU+JSAKICAgIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICAgIG11dGF0ZShjb2xsZWN0aW9uX2RhdGUgPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICAgIGlubmVyX2pvaW4oZHVyYXRpb25fdGVtcHMsIGpvaW5fYnkoY29sbGVjdGlvbl9kYXRlID09IGRhdGUpKSAlPiUgCiAgICBwaXZvdF9sb25nZXIoY29scyA9IGMoY29sbGVjdGlvbl90ZW1wLCBjb250YWlucygiZGF5XyIpKSwKICAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWUiLCAKICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwcmVkaWN0b3IiKSAlPiUgIAogICAgZ3JvdXBfYnkoc3BfbmFtZSwgcHJlZGljdG9yKSAlPiUgCiAgICBzdW1tYXJpc2UoY29ycmVsYXRpb24gPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGVzdGltYXRlLAogICAgICAgICAgICAgIHAudmFsdWUgPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJHAudmFsdWUsCiAgICAgICAgICAgICAgY2lfbG93ID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsxXSwKICAgICAgICAgICAgICBjaV9oaWdoID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsyXSwKICAgICAgICAgICAgICAuZ3JvdXBzID0gImtlZXAiKSAlPiUgCiAgICBmaWx0ZXIocHJlZGljdG9yICE9ICJjb2xsZWN0aW9uX3RlbXAiKSAlPiUgCiAgICBtdXRhdGUoc2lnID0gaWZlbHNlKHAudmFsdWUgPDAuMDUsICJTaWcuIiwgIk5vbiBTaWcuIikpICU+JSAKICAgIHNlcGFyYXRlKHByZWRpY3RvciwgIl9kYXlfIiwgaW50byA9IGMoTkEsICJwYXJhbWV0ZXIiKSkgJT4lIAogICAgbXV0YXRlKGR1cmF0aW9uID0gaSkKICAKICBjb3JyX3ZhbHMgPSBiaW5kX3Jvd3MoY29ycl92YWxzLCBjb3JyX2RhdGEpCn0KCmNvbGxfY29yciA9IGZ1bGxfZGF0YSAlPiUKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIG51bV9jb2xscyRzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBzdW1tYXJpc2UoY29ycmVsYXRpb24gPSBjb3IudGVzdChjdG1heCwgY29sbGVjdGlvbl90ZW1wKSRlc3RpbWF0ZSwKICAgICAgICAgICAgcC52YWx1ZSA9IGNvci50ZXN0KGN0bWF4LCBjb2xsZWN0aW9uX3RlbXApJHAudmFsdWUsCiAgICAgICAgICAgIGNpX2xvdyA9IGNvci50ZXN0KGN0bWF4LCBjb2xsZWN0aW9uX3RlbXApJGNvbmYuaW50WzFdLAogICAgICAgICAgICBjaV9oaWdoID0gY29yLnRlc3QoY3RtYXgsIGNvbGxlY3Rpb25fdGVtcCkkY29uZi5pbnRbMl0pICU+JSAKICBtdXRhdGUoc2lnID0gaWZlbHNlKHAudmFsdWUgPDAuMDUsICJTaWcuIiwgIk5vbiBTaWcuIikpICU+JSAKICBtdXRhdGUoZHVyYXRpb24gPSAwLAogICAgICAgICBwYXJhbWV0ZXIgPSAiY29sbF90ZW1wIikKCmNvcnJfdmFscyA9IGNvcnJfdmFscyAlPiUgIAogIG11dGF0ZShkdXJhdGlvbiA9IGFzLm51bWVyaWMoZHVyYXRpb24pKSAlPiUgCiAgYmluZF9yb3dzKGNvbGxfY29ycikKCmBgYAoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTYsIGluY2x1ZGUgPSBGfQpjb3JyX3ZhbHMgJT4lIAogIG11dGF0ZShwYXJhbWV0ZXIgPSBmY3RfcmVsZXZlbChwYXJhbWV0ZXIsIGMoIm1pbiIsICJtYXgiLCAicmFuZ2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lYW4iLCAibWVkIiwgInZhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWVhbl9taW4iLCAibWVhbl9tYXgiLCAibWVhbl9yYW5nZSIpKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGR1cmF0aW9uLCB5ID0gY29ycmVsYXRpb24sIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoLn5wYXJhbWV0ZXIpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAwLjkpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuNSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiRHVyYXRpb24gKGRheXMpIiwKICAgICAgIHkgPSAiQ29ycmVsYXRpb24iLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCmBgYAoKYGBge3IgcHJlZGljdG9yLWNvcnJlbGF0aW9ucywgaW5jbHVkZSA9IEZ9CiMgU2hvd24gaGVyZSBhcmUgdGhlIHRvcCB0aHJlZSBmYWN0b3JzIGZvciBlYWNoIHNwZWNpZXMuIAoKIyBjb3JyX3ZhbHMgPSBmdWxsX2RhdGEgJT4lCiMgICBmaWx0ZXIoc3BfbmFtZSAlaW4lIG51bV9jb2xscyRzcF9uYW1lKSAlPiUgCiMgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiMgICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiMgICBmdWxsX2pvaW4odGVtcF9wcmVkaWN0b3JzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGNvbGxlY3Rpb25fdGVtcCwgbWVhbl90ZW1wOnRhaWwobmFtZXMoLiksIDEpKSwKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWUiLCAKIyAgICAgICAgICAgICAgICBuYW1lc190byA9ICJwcmVkaWN0b3IiKSAlPiUgIAojICAgZ3JvdXBfYnkoc3BfbmFtZSwgcHJlZGljdG9yKSAlPiUgCiMgICBzdW1tYXJpc2UoY29ycmVsYXRpb24gPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGVzdGltYXRlLAojICAgICAgICAgICAgIHAudmFsdWUgPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJHAudmFsdWUsCiMgICAgICAgICAgICAgY2lfbG93ID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsxXSwKIyAgICAgICAgICAgICBjaV9oaWdoID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsyXSkgJT4lIAojICAgbXV0YXRlKHNpZyA9IGlmZWxzZShwLnZhbHVlIDwwLjA1LCAiU2lnLiIsICJOb24gU2lnLiIpKQoKY29ycl92YWxzICU+JSAgCiAgZmlsdGVyKHNpZyA9PSAiU2lnLiIpICU+JSAKICBkcm9wX25hKGNvcnJlbGF0aW9uKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lCiAgYXJyYW5nZShkZXNjKGNvcnJlbGF0aW9uKSkgJT4lIAogIHNsaWNlX2hlYWQobiA9IDMpICU+JSAKICBzZWxlY3QoIlNwZWNpZXMiID0gc3BfbmFtZSwgIlByZWRpY3RvciIgPSBwYXJhbWV0ZXIsICJEdXJhdGlvbiIgPSBkdXJhdGlvbiwgIkNvcnJlbGF0aW9uIiA9IGNvcnJlbGF0aW9uLCAiUC1WYWx1ZSIgPSBwLnZhbHVlKSAlPiUgCiAga25pdHI6OmthYmxlKGFsaWduID0gImMiKQpgYGAKCmBgYHtyIGFjYy1kdXJhdGlvbi1wbG90LCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD00LCBpbmNsdWRlID0gRn0KIyBQaGVub3R5cGljIHZhcmlhdGlvbiAobGlrZSBhY2NsaW1hdGlvbiBvZiB0aGVybWFsIGxpbWl0cykgaXMgYSBwaHlzaW9sb2dpY2FsIHByb2Nlc3MuIGRlcGVuZGluZyBvbiB0aGUgbWVjaGFuaXN0aWMgdW5kZXJwaW5uaW5ncyAoY2hhbmdlcyBpbiBIU1AgZXhwcmVzc2lvbiwgZXRjLiksIHRoZSBhbW91bnQgb2YgdGltZSBpdCB0YWtlcyBmb3IgYW4gaW5kaXZpZHVhbCB0byBhY2NsaW1hdGUgbWF5IHZhcnkgYmFzZWQgb24gYm9keSBzaXplIChsYXJnZXIgc3BlY2llcywgbW9yZSBjZWxscywgbW9yZSB0aW1lIHJlcXVpcmVkIHRvIGFjY2xpbWF0ZSkuIFNob3duIGhlcmUgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBlbnZpcm9ubWVudGFsIGFjY2xpbWF0aW9uIHdpbmRvdyB0aGUgY29wZXBvZHMgYXBwZWFyIHRvIGJlIHJlc3BvbmRpbmcgdG8uICAKCm1lYW5fc2l6ZXMgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgIAogIHN1bW1hcmlzZShtZWFuX3NpemUgPSBtZWFuKHNpemUsIG5hLnJtID0gVCkpCgpjb3JyX3ZhbHMgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBmaWx0ZXIoY29ycmVsYXRpb24gPT0gbWF4KGNvcnJlbGF0aW9uKSkgJT4lICAKICBpbm5lcl9qb2luKG1lYW5fc2l6ZXMsIGJ5ID0gInNwX25hbWUiKSAlPiUgCiAgc2VsZWN0KHNwX25hbWUsIGR1cmF0aW9uLCBtZWFuX3NpemUpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9zaXplLCB5ID0gZHVyYXRpb24pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNwX25hbWUpLCAKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJNZWFuIEZlbWFsZSBTaXplIChtbSkiLAogICAgICAgeSA9ICJBY2NsaW1hdGlvbiBEdXJhdGlvbiIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgojIyBUcmFpdCBWYXJpYXRpb24gCgpTaG93biBiZWxvdyBhcmUgdGhlIGNsdXRjaCBzaXplIGRpc3RyaWJ1dGlvbnMgZm9yIHRoZSB0aHJlZSBkaWFwdG9taWlkIHNwZWNpZXMsIHdoaWNoIHByb2R1Y2UgZWdnIHNhY3MgdGhhdCBhbGxvdyBmb3IgZWFzeSBxdWFudGlmaWNhdGlvbiBvZiBmZWN1bmRpdHkuIAoKYGBge3IgZmVjdW5kaXR5LWhpc3RvZ3JhbSwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9MTB9CmZ1bGxfZGF0YSAlPiUgIAogIGRyb3BfbmEoZmVjdW5kaXR5KSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGZlY3VuZGl0eSwgZmlsbCA9IHNwX25hbWVfc3ViKSkgKyAKICBmYWNldF93cmFwKC5+c3BfbmFtZV9zdWIsIG5jb2wgPSAxKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMikgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIpICsKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCk9uZSBvZiB0aGUgbWFpbiBhaW1zIG9mIHRoaXMgcHJvamVjdCBpcyB0byBleGFtaW5lIHRoZSBwYXR0ZXJucyBhbmQgcHJvY2Vzc2VzIGRyaXZpbmcgdmFyaWF0aW9uIGluIHVwcGVyIHRoZXJtYWwgbGltaXRzIGFjcm9zcyB0aGVzZSBzcGVjaWVzIG9mIGNvcGVwb2RzLiAKCiMjIyBWYXJpYXRpb24gd2l0aCB0ZW1wZXJhdHVyZSAKCldlIGV4cGVjdCBvbmUgb2YgdGhlIHByaW1hcnkgZHJpdmVycyBvZiBjb3BlcG9kIHRoZXJtYWwgbGltaXRzIHRvIGJlIHRlbXBlcmF0dXJlLiBUaGUgY29ycmVsYXRpb24gYW5hbHlzaXMgaGFzIHNob3duIHRoYXQgdGhlIGNvcGVwb2RzIGFyZSBnZW5lcmFsbHkgKGFsdGhvdWdoIG5vdCBhbHdheXMpIHJlc3BvbmRpbmcgdG8gdGhlIHJlY2VudCB0aGVybWFsIGVudmlyb25tZW50LiBTaG93biBiZWxvdyBhcmUgdGhlcm1hbCBsaW1pdHMsIGJvZHkgc2l6ZSwgYW5kIGZlY3VuZGl0eSB2YWx1ZXMgcGxvdHRlZCBhZ2FpbnN0IHRoZSB0ZW1wZXJhdHVyZSBhdCB0aGUgdGltZSBvZiBjb2xsZWN0aW9uLiBBbHNvIHNob3duIGlzIHdhcm1pbmcgdG9sZXJhbmNlLCBjYWxjdWxhdGVkIGFzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdXBwZXIgdGhlcm1hbCBsaW1pdCBhbmQgdGhlIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuIAoKV2UgZ2VuZXJhbGx5IHNlZSBhbiBpbmNyZWFzZSBpbiB0aGVybWFsIGxpbWl0cyB3aXRoIGluY3JlYXNpbmcgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSwgYSBzbGlnaHQgZGVjcmVhc2UgaW4gYm9keSBzaXplLCBhbmQgdmFyaWFibGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRlbXBlcmF0dXJlIGFuZCBmZWN1bmRpdHkuIEFsbCBzcGVjaWVzIG1haW50YWluZWQgc29tZSBkZWdyZWUgb2YgYnVmZmVyIGJldHdlZW4gZW52aXJvbm1lbnRhbCB0ZW1wZXJhdHVyZXMgYW5kIHVwcGVyIHRoZXJtYWwgbGltaXRzLCBidXQgKkVwaXNjaHVyYSogYW5kICpMLiBtaW51dHVzKiBhcHByb2FjaGVkIHRoZWlyIHVwcGVyIHRoZXJtYWwgbGltaXRzIGR1cmluZyB0aGUgd2FybWVzdCBjb2xsZWN0aW9ucyBkdXJpbmcgdGhlIHN1bW1lci4gCgpgYGB7ciB0cmFpdC1jb2xsLXRlbXAtcGxvdHMsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KY3RtYXhfdGVtcCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArICAgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnNpemVfdGVtcCA9IGdncGxvdChmaWx0ZXIoZnVsbF9kYXRhLCBzZXggIT0gImp1dmVuaWxlIiksIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJMZW5ndGggKG1tKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgp3dF90ZW1wID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSB3YXJtaW5nX3RvbCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJXYXJtaW5nIFRvbGVyYW5jZSAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCmVnZ3NfdGVtcCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gZmVjdW5kaXR5LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGluZXdpZHRoID0gMykgKwogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICB5ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UoY3RtYXhfdGVtcCwgc2l6ZV90ZW1wLCB3dF90ZW1wLCBlZ2dzX3RlbXAsIAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJyaWdodCIpCmBgYAoKYGBge3IgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0Kc3BfY3RtYXhfdGVtcCA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNwX25hbWUgIT0gIk9zcGhyYW50aWN1bSBsYWJyb25lY3R1bSIpICU+JSAKICBtdXRhdGUoc3BfbmFtZSA9IGFzLmZhY3RvcihzcF9uYW1lKSwKICAgICAgICAgc3BfbmFtZSA9IGZjdF9yZW9yZGVyKHNwX25hbWUsIGN0bWF4LCAuZGVzYyA9IFQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC4yKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyIHNhbXBsZS1jdG1heC1zdW1tYXJ5LCBmaWcud2lkdGg9MTQsIGZpZy5oZWlnaHQ9NX0KZ2dhcnJhbmdlKHNhbXBsZV9kYXRlc19wbG90LCBzcF9jdG1heF90ZW1wLCBucm93ID0gMSwgCiAgICAgICAgICBsYWJlbHMgPSAiQVVUTyIpCmBgYAoKCgpUZW1wZXJhdHVyZSBkZXBlbmRlbmNlIGlzIHJlbGF0aXZlbHkgd2VhayBpbiAqTC4gc2ljaWxpcyosIGVzcGVjaWFsbHkgYXQgY29vbGVyIHRlbXBlcmF0dXJlcy4gV2Ugd2lsbCByZXR1cm4gdG8gdGhpcyBmZWF0dXJlIGxhdGVyIGluIHRoZSByZXBvcnQsIGJ1dCBmb3Igbm93IHdlIHdpbGwgbm90ZSB0aGF0IHRoZXJlIGFyZSB0d28gc2l6ZSBtb3JwaHMgaW4gdGhpcyBzcGVjaWVzLCB3aGljaCBhcHBlYXIgdG8gcmVzcG9uZCBkaWZmZXJlbnRseSB0byBkZWNyZWFzZXMgaW4gdGVtcGVyYXR1cmUuIFRoZXJlIGFyZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBtb3JwaHMgYW5kIGhvdyB0ZW1wZXJhdHVyZSBhZmZlY3RzIENUbWF4LiAKYGBge3J9Cm1vcnBoX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIgJiBzcGVjaWVzID09ICJsZXB0b2RpYXB0b211c19zaWNpbGlzIikgJT4lICBtdXRhdGUoc3BfbmFtZSA9IGNhc2Vfd2hlbigKICAgIHNwX25hbWUgPT0gIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiICYgc2l6ZSA+PSAwLjg5IH4gIkxhcmdlIiwKICAgIHNwX25hbWUgPT0gIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiICYgc2l6ZSA8IDAuODkgfiAiU21hbGwiLAogICAgLmRlZmF1bHQgPSBzcF9uYW1lCiAgKSkKCgpnZ3Bsb3QobW9ycGhfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULCBsaW5ld2lkdGggPSAyKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgptb3JwaC5tb2RlbCA9IGxtKGRhdGEgPSBtb3JwaF9kYXRhLCAKICAgICAgICAgICAgICAgICBjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCAqIHNwX25hbWUpCgprbml0cjo6a2FibGUoY2FyOjpBbm92YShtb3JwaC5tb2RlbCwgdHlwZSA9ICJJSUkiLCB0ZXN0ID0gIkYiKSkKCiNzdW1tYXJ5KG1vcnBoLm1vZGVsKQoKbW9ycGguZW0gPSBlbW1lYW5zOjplbXRyZW5kcyhtb3JwaC5tb2RlbCwgInNwX25hbWUiLCB2YXIgPSAiY29sbGVjdGlvbl90ZW1wIikKCmtuaXRyOjprYWJsZShwYWlycyhtb3JwaC5lbSkpCmBgYAoKYGBge3IgY3RtYXgtcmFuZ2UtcGxvdCwgaW5jbHVkZSA9IEZ9CmZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCkgJT4lICAKICBzdW1tYXJpc2UoImN0bWF4X3JhbmdlIiA9IG1heChjdG1heCkgLSBtaW4oY3RtYXgpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksCiAgICAgICAgICAgICJzYW1wbGVfc2l6ZSIgPSBuKCkpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAhPSAiTGVwdG9kb3JhIGtpbmR0aSIpICU+JSAKICBmaWx0ZXIoc2FtcGxlX3NpemUgPiAzKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXhfdmFyLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KCkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKYGBgCgpgYGB7ciBjdG1heC1jb2xsLXRlbXAtbW9kZWwsIGluY2x1ZGUgPSBGfQojIGFkdWx0X2RhdGEgPSBmdWxsX2RhdGEgJT4lIAojICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikKCm1vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lICAKICBkcm9wX25hKHNpemUsIGN0bWF4KSAlPiUgIAogIG11dGF0ZSh0ZW1wX2NlbnQgPSBzY2FsZShjb2xsZWN0aW9uX3RlbXAsIGNlbnRlciA9IFQsIHNjYWxlID0gRiksCiAgICAgICAgIHNpemVfY2VudCA9IHNjYWxlKHNpemUsIGNlbnRlciA9IFQsIHNjYWxlID0gRikpCgpjdG1heF90ZW1wLm1vZGVsID0gbG0oZGF0YSA9IG1vZGVsX2RhdGEsIGN0bWF4IH4gdGVtcF9jZW50ICogc3BfbmFtZSkKc2l6ZV90ZW1wLm1vZGVsID0gbG0oZGF0YSA9IG1vZGVsX2RhdGEsIHNpemUgfiB0ZW1wX2NlbnQgKiBzcF9uYW1lKQpmZWN1bmRfdGVtcC5tb2RlbCA9IGxtKGRhdGEgPSBkcm9wX25hKG1vZGVsX2RhdGEsIGZlY3VuZGl0eSksIGZlY3VuZGl0eSB+IHRlbXBfY2VudCAqIHNwX25hbWUpCgpmZWN1bmRpdHlfcmVzaWRzID0gY2JpbmQoZHJvcF9uYShtb2RlbF9kYXRhLCBmZWN1bmRpdHkpLCAiZmVjdW5kaXR5X3Jlc2lkcyIgPSBmZWN1bmRfdGVtcC5tb2RlbCRyZXNpZHVhbHMpICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBleHBfZGF0ZSwgcmVwbGljYXRlLCBzcGVjaWVzLCB0dWJlLCBmZWN1bmRpdHlfcmVzaWRzKQoKY3RtYXhfcmVzaWRzID0gY2JpbmQobW9kZWxfZGF0YSwgInJlc2lkcyIgPSBjdG1heF90ZW1wLm1vZGVsJHJlc2lkdWFscywgInNpemVfcmVzaWRzIiA9IHNpemVfdGVtcC5tb2RlbCRyZXNpZHVhbHMpICU+JSAKICBsZWZ0X2pvaW4oZmVjdW5kaXR5X3Jlc2lkcykKCmBgYAoKQ29wZXBvZHMgc3BlbnQgc2V2ZXJhbCBkYXlzIGluIGxhYiBkdXJpbmcgZXhwZXJpbWVudHMuIFNob3duIGJlbG93IGFyZSB0aGUgQ1RtYXggcmVzaWR1YWxzICh0YWtlbiBmcm9tIGEgbW9kZWwgb2YgQ1RtYXggYWdhaW5zdCBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlKSBwbG90dGVkIGFnYWluc3QgdGhlIHRpbWUgc3BlbnQgaW4gbGFiIGJlZm9yZSBtZWFzdXJlbWVudHMgd2VyZSBtYWRlLiBJbmRpdmlkdWFsIHJlZ3Jlc3Npb25zIGFyZSBzaG93biBmb3IgdGhlIHJlc2lkdWFscyBhZ2FpbnN0IGRheXMgaW4gbGFiIGZvciBlYWNoIGNvbGxlY3Rpb24uIFdlIGNhbiBzZWUgY2xlYXJseSB0aGF0IHRoZXJtYWwgbGltaXRzIGFyZSBmYWlybHkgc3RhYmxlIG92ZXIgdGltZS4gCgpgYGB7ciBjdG1heC10aW1lLWluLWxhYiwgZmlnLndpZHRoPTE1LCBmaWcuaGVpZ2h0PTEwfQpnZ3Bsb3QoY3RtYXhfcmVzaWRzLCBhZXMoeCA9IGRheXNfaW5fbGFiLCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lLCBncm91cCA9IGNvbGxlY3Rpb25fZGF0ZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gNCwgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAxKSArIAogICNzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwOjUpKSArIAogIGxhYnMoeCA9ICJEYXlzIGluIGxhYiIsIAogICAgICAgeSA9ICJDVG1heCBSZXNpZHVhbHMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKYGBge3IgQVJSLWxpbWl0cy1wbG90LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQpmdWxsLm1vZGVsID0gbG1lNDo6bG1lcihkYXRhID0gbW9kZWxfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgY3RtYXggfiBzZXggKyB0ZW1wX2NlbnQgKyBzaXplX2NlbnQgKyBkZXZfZWdncyArIGxpcGlkcyArIHBhdGhvZ2VuICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgKyBkYXlzX2luX2xhYiArIHRlbXBfY2VudCArIHNpemVfY2VudHxzcF9uYW1lKSkKCmNhcjo6QW5vdmEoZnVsbC5tb2RlbCkKCmZpeGVkID0gZml4ZWYoZnVsbC5tb2RlbCkKCm1vZGVsX2NvZWZzID0gY29lZmZpY2llbnRzKGZ1bGwubW9kZWwpJGBzcF9uYW1lYCAlPiUgIAogIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAic3BlY2llcyIpICU+JSAKICBzZXBhcmF0ZShzcGVjaWVzLCBpbnRvID0gYygic3BlY2llcyIpLCBzZXAgPSAiOiIpICU+JSAKICBzZWxlY3Qoc3BlY2llcywgImludGVyY2VwdCIgPSAiKEludGVyY2VwdCkiLCB0ZW1wX2NlbnQsIHNpemVfY2VudCwgZGF5c19pbl9sYWIpCgpnZ3Bsb3QobW9kZWxfY29lZnMsIGFlcyh4ID0gaW50ZXJjZXB0LCB5ID0gdGVtcF9jZW50KSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc3BlY2llcyksCiAgICAgICAgICAgICBzaXplID0gNikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiU3BlY2llcyBJbnRlcmNlcHQiLCAKICAgICAgIHkgPSAiQVJSIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgoKYXJyX2NvbWJpbmVkID0gc3ludGhfYXJyICU+JQogIGZpbHRlcihtZWFzdXJlID09ICJ1cHBlciIgJiBtZWFuX2xpbSA+IDIwKSAlPiUgCiAgc2VsZWN0KCJncm91cCIgPSBnZW51cywgYXJyLCBtZWFuX2xpbSkgJT4lIAogIG11dGF0ZSgiZGF0YXNldCIgPSAic3ludGhlc2lzIikgJT4lIAogIGJpbmRfcm93cygKICAgIHNlbGVjdChtb2RlbF9jb2VmcywgImdyb3VwIiA9IHNwZWNpZXMsICdhcnInID0gdGVtcF9jZW50LCAnbWVhbl9saW0nID0gaW50ZXJjZXB0KQogICkgJT4lIAogIG11dGF0ZShkYXRhc2V0ID0gaWZfZWxzZShpcy5uYShkYXRhc2V0KSwgIm5ldyBkYXRhIiwgInN5bnRoZXNpcyIpKQoKCmdncGxvdChhcnJfY29tYmluZWQsIGFlcyh4ID0gbWVhbl9saW0sIHkgPSBhcnIpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMiwgY29sb3VyID0gImdyZXkzMCIpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGFycl9jb21iaW5lZCwgZGF0YXNldCAhPSAibmV3IGRhdGEiKSwgCiAgICAgICAgICAgICBzaXplID0gNCwgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihhcnJfY29tYmluZWQsIGRhdGFzZXQgPT0gIm5ldyBkYXRhIiksCiAgICAgICAgICAgICBhZXMoY29sb3VyID0gZ3JvdXApLCAKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJUaGVybWFsIExpbWl0IiwgCiAgICAgICB5ID0gIkFSUiIsIAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKYGBgCgpUaGUgdGVybSAiYWNjbGltYXRpb24gcmVzcG9uc2UgcmF0aW8iIGlzIG9mdGVuIHVzZWQgdG8gZGVzY3JpYmUgdGhlIGVmZmVjdCBvZiB0ZW1wZXJhdHVyZSBvbiB0aGVybWFsIGxpbWl0cy4gVGhlIEFSUiBpcyBjYWxjdWxhdGVkIGFzIHRoZSBjaGFuZ2UgaW4gdGhlcm1hbCBsaW1pdHMgcGVyIGRlZ3JlZSBjaGFuZ2UgaW4gYWNjbGltYXRpb24gdGVtcGVyYXR1cmUuIEZvciBvdXIgZGF0YSwgd2Ugd2lsbCBlc3RpbWF0ZSBBUlIgYXMgdGhlIHNsb3BlIG9mIENUbWF4IGFnYWluc3QgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZS4gVGhlc2Ugc2xvcGVzIHdlcmUgdGFrZW4gZnJvbSBhIHJlZ3Jlc3Npb24gb2YgQ1RtYXggYWdhaW5zdCBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlIGFuZCBib2R5IHNpemUuIFR3byBkaWZmZXJlbnQgbW9kZWwgdHlwZXMgd2VyZSB1c2VkLCBhIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBhbmQgYSBtaXhlZCBlZmZlY3RzIG1vZGVsLiBUaGUgZXN0aW1hdGVkIEFSUiB2YWx1ZXMgd2VyZSBnZW5lcmFsbHkgaGlnaGx5IHNpbWlsYXIgYmV0d2VlbiB0aGUgbW9kZWwgdHlwZXMgdXNlZC4KCmBgYHtyIGFyci1jb21wLXBsb3QsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTEwLCBpbmNsdWRlID0gRn0KY29lZl9tb2RlbF9kYXRhID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBzZXgpICU+JSAKICBmaWx0ZXIobigpID4gMyAmICFzdHJfZGV0ZWN0KHNwX25hbWUsIHBhdHRlcm4gPSAia2luZHRpIikpIAoKY29lZl9uID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBzZXgpICU+JSAKICBmaWx0ZXIobigpID4gNSkgJT4lIAogIHN1bW1hcmlzZShzYW1wbGVfbiA9IG4oKSwgCiAgICAgICAgICAgIG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4KSkKCkFSUl92YWxzID0gY29lZl9tb2RlbF9kYXRhICU+JSAKICBkbyhicm9vbTo6dGlkeShsbShjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCArIHNpemUsIGRhdGEgPSAuKSkpICU+JSAKICBmaWx0ZXIodGVybSA9PSAiY29sbGVjdGlvbl90ZW1wIikgJT4lIAogIHNlbGVjdChzcF9uYW1lLCBzZXgsICJBUlIiID0gZXN0aW1hdGUsIHN0ZC5lcnJvcikgJT4lIAogIGFycmFuZ2UoQVJSKSAlPiUgCiAgaW5uZXJfam9pbihjb2VmX24sIGJ5ID0gYygic3BfbmFtZSIsICJzZXgiKSkKCkFSUl92YWxzICU+JSAKICBzZWxlY3QoIlNwZWNpZXMiID0gc3BfbmFtZSwgCiAgICAgICAgICJHcm91cCIgPSBzZXgsIAogICAgICAgICAiTiIgPSBzYW1wbGVfbiwKICAgICAgICAgQVJSLCAKICAgICAgICAgIkVycm9yIiA9IHN0ZC5lcnJvcikgJT4lIAogIGtuaXRyOjprYWJsZSgpCgptbGVfY29lZnMgPSBjb2VmZmljaWVudHMoZnVsbC5tb2RlbCkkYHNwX25hbWVgICU+JSAKICBtdXRhdGUoImdyb3VwIiA9IHJvd25hbWVzKC4pKSAlPiUgCiAgc2VsZWN0KGdyb3VwLCAiaW50ZXJjZXB0IiA9ICIoSW50ZXJjZXB0KSIsICJBUlIiID0gdGVtcF9jZW50LCBzaXplX2NlbnQpICU+JSAKICByZW1vdmVfcm93bmFtZXMoKQoKbWxlX0FSUiA9IG1sZV9jb2VmcyAlPiUgIAogIHNlbGVjdChzcF9uYW1lID0gZ3JvdXAsIEFSUikgJT4lIAogIG11dGF0ZSgibW9kZWwiID0gIm1peGVkIGVmZmVjdHMiKSAgJT4lIAogIGlubmVyX2pvaW4oY29lZl9uLCBieSA9IGMoInNwX25hbWUiKSkKCkFSUl9jb21wID0gYmluZF9yb3dzKG1sZV9BUlIsIAogICAgICAgICAgICAgICAgICAgICBtdXRhdGUoQVJSX3ZhbHMsICJtb2RlbCIgPSAibGluZWFyIikpCgpBUlJfY29tcCAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbW9kZWwsIHkgPSBBUlIsIGdyb3VwID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfZ3JpZChzcF9uYW1lfnNleCkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuNSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAwLjUsIDEpKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwMCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCgpgYGAKCiMjIyBTZXggYW5kIHN0YWdlIHZhcmlhdGlvbiBpbiB0aGVybWFsIGxpbWl0cyAKUHJldmlvdXMgc2VjdGlvbnMgaGF2ZSBnZW5lcmFsbHkgbHVtcGVkIGp1dmVuaWxlLCBmZW1hbGUsIGFuZCBtYWxlIGluZGl2aWR1YWxzIHRvZ2V0aGVyLiBUaGVyZSBtYXkgYmUgaW1wb3J0YW50IHN0YWdlLSBvciBzZXgtc3BlY2lmaWMgZGlmZmVyZW5jZXMgaW4gQ1RtYXggdGhvdWdoLiBGb3Igc2V2ZXJhbCBzcGVjaWVzLCB3ZSBoYXZlIG1lYXN1cmVtZW50cyBmb3IgaW5kaXZpZHVhbHMgaW4gZGlmZmVyZW50IHN0YWdlcyBvciBvZiBkaWZmZXJlbnQgc2V4ZXMuIAoKYGBge3Igc2V4LXN0YWdlLXRhYmxlfQpzZXhfc2FtcGxlX3NpemVzID0gY3RtYXhfcmVzaWRzICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgIAogIHN1bW1hcmlzZShudW0gPSBuKCkpICU+JSAgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IHNwX25hbWUsCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNleCwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBudW0sCiAgICAgICAgICAgICAgdmFsdWVzX2ZpbGwgPSAwKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJKdXZlbmlsZSIgPSBqdXZlbmlsZSwgIkZlbWFsZSIgPSBmZW1hbGUsICJNYWxlIiA9IG1hbGUpCgprbml0cjo6a2FibGUoc2V4X3NhbXBsZV9zaXplcywgYWxpZ24gPSAiYyIpCmBgYAoKVGhlIGZlbWFsZS1tYWxlIGFuZCBmZW1hbGUtanV2ZW5pbGUgY29tcGFyaXNvbnMgc2hvdyB0aGF0IHRoZXJlIGFyZSBnZW5lcmFsbHkgbm8gZGlmZmVyZW5jZXMgaW4gdGhlcm1hbCBsaW1pdHMgYmV0d2VlbiB0aGVzZSBncm91cHMuIAoKYGBge3IgY3RtYXgtc2V4LCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03fQpjdG1heF9yZXNpZHMgJT4lIAogIGZpbHRlcihzcF9uYW1lICVpbiUgZmlsdGVyKHNleF9zYW1wbGVfc2l6ZXMsIE1hbGUgPiAwLCBGZW1hbGUgPiAwKSRTcGVjaWVzICYgCiAgICAgICAgICAgc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzZXgsIHkgPSByZXNpZHMsIGNvbG91ciA9IHNwX25hbWUsIGdyb3VwID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIG5jb2wgPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoZWlnaHQgPSAwLCB3aWR0aCA9IDAuMDUpKSArICAKICBsYWJzKHggPSAiU2V4IiwgCiAgICAgICB5ID0gIkNUbWF4IFJlc2lkdWFscyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyIGN0bWF4LXN0YWdlLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03fQpjdG1heF9yZXNpZHMgJT4lIAogIGZpbHRlcihzcF9uYW1lICVpbiUgZmlsdGVyKHNleF9zYW1wbGVfc2l6ZXMsIEp1dmVuaWxlID4gMCAmIEZlbWFsZSA+IDApJFNwZWNpZXMgJiAKICAgICAgICAgICBzZXggIT0gIm1hbGUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2V4LCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lLCBncm91cCA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41LAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaGVpZ2h0ID0gMCwgd2lkdGggPSAwLjA1KSkgKyAgCiAgbGFicyh4ID0gIlNleCIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyIHRyYWl0LXZhcmlhbmNlLWNvbGwtdGVtcCwgaW5jbHVkZSA9IEZ9CiMgCiMgR2l2ZW4gdGhlIGxvbmcgZ2VuZXJhdGlvbiB0aW1lcyBvZiB0aGVzZSBjb3BlcG9kcywgZGVjcmVhc2VzIGluIHRyYWl0IHZhcmlhbmNlIG1heSBpbmRpY2F0ZSBzZWxlY3Rpb24gb3ZlciB0aGUgc2Vhc29uYWwgY3ljbGUuIFNob3duIGJlbG93IGFyZSB0aGUgdmFyaWFuY2UgaW4gb2JzZXJ2ZWQgQ1RtYXggYW5kIHNpemUsIHBsb3R0ZWQgYWdhaW5zdCBjb2xsZWN0aW9uIGRhdGUuIFZhcmlhbmNlIGRlY3JlYXNlcyBpbiAqU2tpc3RvZGlhcHRvbXVzKiwgYnV0IHRoaXMgcGF0dGVybiBpcyBkcml2ZW4gYnkgYSBzaW5nbGUgY29sbGVjdGlvbiB3aXRoIGhpZ2ggdmFyaWFuY2UgZWFybHkgaW4gdGhlIHllYXIuIFNpemUgdmFyaWFuY2UgaW5jcmVhc2VzIHNsaWdodGx5IGluICpTa2lzdG9kaWFwdG9tdXMqLiBWYXJpYW5jZSBpbiBib3RoIENUbWF4IGFuZCBzaXplIGlzIGZhaXJseSBjb25zdGFudCBpbiAqTGVwdG9kaWFwdG9tdXMgbWludXR1cyosIHRoZSBvbmx5IG90aGVyIHNwZWNpZXMgY29sbGVjdGVkIGFjcm9zcyB0aGUgZW50aXJlIHNldCBvZiBzYW1wbGVzIHRodXMgZmFyLiAKIyAKIyBnZ3Bsb3QoZHJvcF9uYShhZHVsdF9zdW1tYXJpZXMsIGN0bWF4X3ZhciksIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXhfdmFyLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKIyAgIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBzY2FsZXMgPSAiZnJlZV95IikgKyAKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiMgICBnZW9tX3Ntb290aChzZSA9IEYpICsgCiMgICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAojICAgICAgICB5ID0gIkNUbWF4IFZhcmlhbmNlIikgKyAKIyAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAojICAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojIAojIGdncGxvdChkcm9wX25hKGFkdWx0X3N1bW1hcmllcywgc2l6ZV92YXIpLCBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IHNpemVfdmFyLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKIyAgIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAojICAgZ2VvbV9wb2ludChzaXplID0gMikgKyAKIyAgIGdlb21fc21vb3RoKHNlID0gRikgKyAKIyAgIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIiwgCiMgICAgICAgIHkgPSAiU2l6ZSBWYXJpYW5jZSIpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKIyAgIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKIyAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgoKIyMjIFRyYWl0IENvcnJlbGF0aW9ucyBhbmQgVHJhZGUtb2ZmcwoKQSByZWxhdGlvbnNoaXAgYmV0d2VlbiBzaXplIGFuZCB1cHBlciB0aGVybWFsIGxpbWl0cyBoYXMgYmVlbiBzdWdnZXN0ZWQgaW4gYSB3aWRlIHJhbmdlIG9mIG90aGVyIHRheGEuIFNob3duIGJlbG93IGFyZSB0aGUgbWVhc3VyZWQgdXBwZXIgdGhlcm1hbCBsaW1pdHMgcGxvdHRlZCBhZ2FpbnN0IHByb3NvbWUgbGVuZ3RoLiBUaGUgb3ZlcmFsbCByZWxhdGlvbnNoaXAgKGluY2x1c2l2ZSBvZiBhbGwgc3BlY2llcykgaXMgc2hvd24gYXMgdGhlIGJsYWNrIGxpbmUgaW4gdGhlIGJhY2tncm91bmQuIFJlZ3Jlc3Npb25zIGZvciBlYWNoIGluZGl2aWR1YWwgc3BlY2llcyBhcmUgYWxzbyBzaG93bi4gQWNyb3NzIHRoZSBlbnRpcmUgYXNzZW1ibGFnZSwgdGhlcmUgaXMgYSBzdHJvbmcgZGVjcmVhc2UgaW4gdGhlcm1hbCBsaW1pdHMgd2l0aCBpbmNyZWFzaW5nIHNpemUuICAKCmBgYHtyIGN0bWF4LXNpemUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03fQoKZnVsbF9kYXRhICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBnZ3Bsb3QoIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgICBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCksCiAgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgCiAgICAgICAgICAgICAgY29sb3VyID0iYmxhY2siLCAKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAyLjUpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAyKSArIAogIGxhYnMoeCA9ICJMZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmBgYAoKU2hvd24gaGVyZSBpcyB0aGUgcmVsYXRpb25zaGlwIGZvciBlYWNoIHNwZWNpZXMgaW5kaXZpZHVhbGx5LiAKCmBgYHtyIGluZC1zcC1jdG1heC1zaXplLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD02fQpmdWxsX2RhdGEgJT4lIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JSBmaWx0ZXIobigpID4yKSAlPiUgZmlsdGVyKCFzdHJfZGV0ZWN0KHNwX25hbWUsIHBhdHRlcm4gPSAia2luZHRpIikpICU+JSAKICBnZ3Bsb3QoIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+Liwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuOCkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgbGFicyh4ID0gIkxlbmd0aCAobW0pIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKU2hvd24gYmVsb3cgaXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1lYW4gc2l6ZSBhbmQgbWVhbiB0aGVybWFsIGxpbWl0cyBmb3IgZmVtYWxlcyBvZiBlYWNoIHNwZWNpZXMuIFdlIHNlZSB0aGF0IGxhcmdlciBzcGVjaWVzIHdpdGhpbiB0aGUgY29tbXVuaXR5IHRlbmQgdG8gaGF2ZSBhIGxvd2VyIHRoZXJtYWwgbGltaXQgdGhhbiBzbWFsbGVyIHNwZWNpZXMuIAoKYGBge3IgbWVhbi1jdG1heC1tZWFuLXNpemUtcGxvdCwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9NX0KZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBzZXgpICU+JSAKICBzdW1tYXJpemUobWVhbl9jdG1heCA9IG1lYW4oY3RtYXgsIG5hLnJtID0gVCksCiAgICAgICAgICAgIG1lYW5fc2l6ZSA9IG1lYW4oc2l6ZSwgbmEucm0gPSBUKSkgJT4lIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9zaXplLCB5ID0gbWVhbl9jdG1heCkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAyLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNwX25hbWUsIHNoYXBlID0gc2V4KSwKICAgICAgICAgICAgIHNpemUgPSA1KSArIAogIGxhYnMoeCA9ICJMZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpgYGB7ciBjdG1heHJlc2lkcy1zaXplLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgaW5jbHVkZSA9IEZ9CmN0bWF4X3Jlc2lkcyAlPiUgCiAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplX3Jlc2lkcywgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgbGFicyh4ID0gIkxlbmd0aCAobW0pIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKU2hvd24gaGVyZSBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZmVjdW5kaXR5IGFuZCBzaXplLCBzaG93aW5nIHRoZSBjbGFzc2ljIHBhdHRlcm4gb2YgaW5jcmVhc2luZyBlZ2cgcHJvZHVjdGlvbiB3aXRoIGluY3JlYXNpbmcgc2l6ZS4gCgpgYGB7ciBmZWN1bmRpdHktc2l6ZSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTd9CmN0bWF4X3Jlc2lkcyAlPiUgIAogIGRyb3BfbmEoZmVjdW5kaXR5KSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2l6ZSwgeSA9IGZlY3VuZGl0eSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAyKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC41KSArIAogIGxhYnMoeCA9ICJQcm9zb21lIGxlbmd0aCAobW0pIiwgCiAgICAgICB5ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpJbmRpdmlkdWFscyBtYXkgYWxzbyBhbGxvY2F0ZSBlbmVyZ3kgdG8gZGlmZmVyZW50IGZpdG5lc3MgcmVsYXRlZCB0cmFpdHMsIHByaW9yaXRpemluZyByZXByb2R1Y3RpdmUgb3V0cHV0IG92ZXIgZW52aXJvbm1lbnRhbCB0b2xlcmFuY2UsIGZvciBleGFtcGxlLiBTaG93biBiZWxvdyBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gQ1RtYXggcmVzaWR1YWxzIChhZ2FpbiwgY29udHJvbGxpbmcgZm9yIHRoZSBlZmZlY3RzIG9mIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUpIGFnYWluc3QgZmVjdW5kaXR5LiBXZSBjYW4gc2VlIGNsZWFybHkgdGhhdCBpbmRpdmlkdWFscyB3aXRoIGluY3JlYXNlZCBmZWN1bmRpdHkgYXJlIG5vdCBkZWNyZWFzaW5nIHRoZXJtYWwgbGltaXRzLCBzdWdnZXN0aW5nIHRoYXQgdGhlcmUgaXMgbm8gZW5lcmdldGljIHRyYWRlLW9mZiBiZXR3ZWVuIHRoZXNlIHRyYWl0cy4gCgpgYGB7ciwgY3RtYXgtZmVjdW5kaXR5LCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KY3RtYXhfcmVzaWRzICU+JSAgCiAgZHJvcF9uYShmZWN1bmRpdHkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZXNpZHMsIHkgPSBmZWN1bmRpdHlfcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjUpICsgCiAgbGFicyh4ID0gIkNUbWF4IFJlc2lkdWFscyIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgUmVzaWR1YWxzIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCiMjIE90aGVyIHBhdHRlcm5zIGluIHZhcmlhdGlvbiAKCipMZXB0b2RpYXB0b211cyBzaWNpbGlzKiBpcyB0aGUgbW9zdCBhYnVuZGFudCBzcGVjaWVzIGR1cmluZyB0aGUgd2ludGVyLiBUaGVyZSB3YXMgYSBsYXJnZSBzaGlmdCBpbiB0aGUgc2l6ZSBvZiBtYXR1cmUgZmVtYWxlcyB0b3dhcmRzIHRoZSBlbmQgb2YgRGVjZW1iZXIuIFRoZXNlIGxhcmdlIGFuZCBzbWFsbCBpbmRpdmlkdWFscyBhcmUgdGhlIHNhbWUgc3BlY2llcyAoY29uZmlybWVkIHZpYSBDT0kgc2VxdWVuY2luZyksIHN1Z2dlc3RpbmcgdGhpcyBzaGlmdCBtYXkgcmVmbGVjdCBhIHRyYW5zaXRpb24gZnJvbSBvbmUgZ2VuZXJhdGlvbiB0byBhbm90aGVyIGFuZCB0aGF0LCB1bmxpa2UgaW4gbWFueSBvdGhlciBsYWtlcywgdGhlcmUgYXJlIHR3byBnZW5lcmF0aW9ucyBvZiAqTC4gc2ljaWxpcyogcGVyIHllYXIgaW4gTGFrZSBDaGFtcGxhaW4uIFRoaXMgc2l6ZSBkaWZmZXJlbmNlIG1heSBiZSBjYXVzZWQgYnkgZGlmZmVyZW5jZXMgaW4gdGhlIGRldmVsb3BtZW50YWwgZW52aXJvbm1lbnRzLiBGb3IgZXhhbXBsZSwgaW5kaXZpZHVhbHMgZGV2ZWxvcGluZyBpbiBKYW51YXJ5IGdyb3cgdXAgYXQgdmVyeSBsb3cgdGVtcGVyYXR1cmVzLCBhbmQgdGhlcmVmb3JlIG1heSByZWFjaCBsYXJnZXIgc2l6ZXMuIFRoZXNlIGluZGl2aWR1YWxzIG92ZXJzdW1tZXIgaW4gZGVlcCB3YXRlcnMsIHRoZW4gcmUtZW1lcmdlIGluIE9jdG9iZXIgYW5kIHByb2R1Y2UgYSBuZXcgZ2VuZXJhdGlvbi4gV2F0ZXIgdGVtcGVyYXR1cmVzIGFyZSBzdGlsbCBmYWlybHkgaGlnaCB0aHJvdWdoIE5vdmVtYmVyLCB3aGljaCByZXN1bHRzIGluIGEgZ2VuZXJhdGlvbiBvZiBzbWFsbGVyIGluZGl2aWR1YWxzLCB3aGljaCBtYXR1cmUgaW4gdGltZSB0byBwcm9kdWNlIGEgbmV3IGdlbmVyYXRpb24gaW4gSmFudWFyeS4gCgpTaG93biBiZWxvdyBpcyB0aGUgZGlzdHJpYnV0aW9uIG9mIHBhaXJ3aXNlIGRpc3RhbmNlcyBiZXR3ZWVuIENPSSBzZXF1ZW5jZXMgb2YgbGFyZ2UgYW5kIHNtYWxsIG1vcnBocy4gRGlzdGFuY2VzIGluIGJvdGggd2l0aGluLSBhbmQgYWNyb3NzLW1vcnBoIGNvbXBhcmlzb25zIGFyZSBzbWFsbC4gCgpgYGB7cn0KaW5kX2Rpc3QgPSBhcGU6OmRpc3QuZG5hKHNpY19kbmFiaW4sIG1vZGVsID0gInJhdyIpICU+JSBhcy5tYXRyaXggJT4lIAogIGFzX3RpYmJsZSgpICU+JQogIG11dGF0ZSgiaW5kMSIgPSBjb2xuYW1lcyguKSkgJT4lIAogIHBpdm90X2xvbmdlcigtaW5kMSwgbmFtZXNfdG8gPSAiaW5kMiIsIHZhbHVlc190byA9ICJkaXN0IikgJT4lCiAgbXV0YXRlKGluZDEgPSBmYWN0b3IoaW5kMSksCiAgICAgICAgIGluZDIgPSBmYWN0b3IoaW5kMikpICU+JSAKICBmaWx0ZXIoIShpbmQxID09ICJzb3JlMSIgfCBpbmQyID09ICJzb3JlMSIpKSAlPiUgCiAgbXV0YXRlKAogICAgaW5kMSA9IGNhc2Vfd2hlbigKICAgICAgaW5kMSA9PSAiUzEiIH4gInNtYWxsMSIsCiAgICAgIGluZDEgPT0gIlMzIiB+ICJzbWFsbDMiLAogICAgICBpbmQxID09ICJsc2ljMyIgfiAic21hbGw0IiwKICAgICAgaW5kMSA9PSAibHNpYzUiIH4gInNtYWxsNiIsCiAgICAgIGluZDEgPT0gImxzaWM5IiB+ICJzbWFsbDgiLAogICAgICBpbmQxID09ICJsc2ljMTAiIH4gInNtYWxsOSIsCiAgICAgIGluZDEgPT0gImxzaWMxMSIgfiAic21hbGwxMCIsCiAgICAgIGluZDEgPT0gIkwxIiB+ICJsYXJnZTEiLAogICAgICBpbmQxID09ICJMMiIgfiAibGFyZ2UyIiwKICAgICAgaW5kMSA9PSAiTDMiIH4gImxhcmdlMyIsCiAgICAgIGluZDEgPT0gImxzaWMxIiB+ICJsYXJnZTQiLAogICAgICBpbmQxID09ICJsc2ljMiIgfiAibGFyZ2U1IiwKICAgICAgaW5kMSA9PSAibHNpYzciIH4gImxhcmdlNiIsCiAgICAgIGluZDEgPT0gImxzaWM4IiB+ICJsYXJnZTciKSwKICAgIGluZDIgPSBjYXNlX3doZW4oCiAgICAgIGluZDIgPT0gIlMxIiB+ICJzbWFsbDEiLAogICAgICBpbmQyID09ICJTMyIgfiAic21hbGwzIiwKICAgICAgaW5kMiA9PSAibHNpYzMiIH4gInNtYWxsNCIsCiAgICAgIGluZDIgPT0gImxzaWM1IiB+ICJzbWFsbDYiLAogICAgICBpbmQyID09ICJsc2ljOSIgfiAic21hbGw4IiwKICAgICAgaW5kMiA9PSAibHNpYzEwIiB+ICJzbWFsbDkiLAogICAgICBpbmQyID09ICJsc2ljMTEiIH4gInNtYWxsMTAiLAogICAgICBpbmQyID09ICJMMSIgfiAibGFyZ2UxIiwKICAgICAgaW5kMiA9PSAiTDIiIH4gImxhcmdlMiIsCiAgICAgIGluZDIgPT0gIkwzIiB+ICJsYXJnZTMiLAogICAgICBpbmQyID09ICJsc2ljMSIgfiAibGFyZ2U0IiwKICAgICAgaW5kMiA9PSAibHNpYzIiIH4gImxhcmdlNSIsCiAgICAgIGluZDIgPT0gImxzaWM3IiB+ICJsYXJnZTYiLAogICAgICBpbmQyID09ICJsc2ljOCIgfiAibGFyZ2U3IiksCiAgICAnY29tcGFyaXNvbicgPSBjYXNlX3doZW4oCiAgICAgIHN0cl9kZXRlY3QoaW5kMSwgcGF0dGVybiA9ICJsYXJnZSIpICYgc3RyX2RldGVjdChpbmQyLCBwYXR0ZXJuID0gImxhcmdlIikgfiAid2l0aGluIiwKICAgICAgc3RyX2RldGVjdChpbmQxLCBwYXR0ZXJuID0gInNtYWxsIikgJiBzdHJfZGV0ZWN0KGluZDIsIHBhdHRlcm4gPSAic21hbGwiKSB+ICJ3aXRoaW4iLCAKICAgICAgc3RyX2RldGVjdChpbmQxLCBwYXR0ZXJuID0gImxhcmdlIikgJiBzdHJfZGV0ZWN0KGluZDIsIHBhdHRlcm4gPSAic21hbGwiKSB+ICJhY3Jvc3MiLAogICAgICBzdHJfZGV0ZWN0KGluZDEsIHBhdHRlcm4gPSAic21hbGwiKSAmIHN0cl9kZXRlY3QoaW5kMiwgcGF0dGVybiA9ICJsYXJnZSIpIH4gImFjcm9zcyIKICAgICkpIAoKZ2dwbG90KGluZF9kaXN0LCBhZXMoZGlzdCwgZmlsbCA9IGNvbXBhcmlzb24pKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwNSkgKyAKICBsYWJzKHggPSAiRGlzdGFuY2UiKSArIAogIHRoZW1lX21hdHQoKQpgYGAKCgpgYGB7cn0KZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNwX25hbWUgPT0gIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiKSAlPiUgCiAgZmlsdGVyKHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ3JvdXBfYnkoY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgbXV0YXRlKHNpemVfY2VudGVyID0gc2NhbGUoc2l6ZSwgY2VudGVyID0gVCwgc2NhbGUgPSBGKSkgJT4lIAogIGdncGxvdChhZXMoeSA9IGZhY3Rvcihjb2xsZWN0aW9uX2RhdGUpLCB4ID0gc2l6ZSwgZmlsbCA9IGNvbGxlY3Rpb25fdGVtcCkpICsgCiAgZmFjZXRfd3JhcChzZXh+LikgKyAKICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGJhbmR3aWR0aCA9IDAuMDQpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMC44OSkgKyAKICBsYWJzKHggPSAiU2l6ZSAobW0pIiwKICAgICAgIHkgPSAiRGF0ZSIsIAogICAgICAgZmlsbCA9ICJDb2xsLiBUZW1wLiAowrBDKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQpgYGAKCmBgYHtyfQpmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIpICU+JSAKICBmaWx0ZXIoc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBmYWN0b3IoY29sbGVjdGlvbl9kYXRlKSwgeCA9IHNpemUsIGZpbGwgPSBjb2xsZWN0aW9uX3RlbXApKSArIAogIGZhY2V0X3dyYXAoc2V4fi4pICsgCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhiYW5kd2lkdGggPSAwLjA0KSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAuNjkpICsgCiAgbGFicyh4ID0gIlNpemUgKG1tKSIsCiAgICAgICB5ID0gIkRhdGUiLCAKICAgICAgIGZpbGwgPSAiQ29sbC4gVGVtcC4gKMKwQykiKSArIAogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLjUsMC45KSkgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCmBgYAoKIyMgRGlzdHJpYnV0aW9uIExhZyBOb24tTGluZWFyIE1vZGVsIChETE5NIGFwcHJvYWNoKSAKCkRpc3RyaWJ1dGVkIGxhZyBtb2RlbHMgZXhhbWluZSBhIHJlc3BvbnNlIHZhcmlhYmxlLCBtZWFzdXJlZCBhdCBtdWx0aXBsZSB0aW1lIHBvaW50cywgYXMgYSBmdW5jdGlvbiBvZiB0aGUgbGFnZ2VkIG9jY3VycmVuY2Ugb2Ygc29tZSBwcmVkaWN0b3IgdmFyaWFibGUgKHJlc3BvbnNlIHkgYXQgdGltZSB0IGFzIGEgZnVuY3Rpb24gb2YgcHJlZGl0b3IgeCh0LWxhZykuIFRoaXMgbWV0aG9kIHV0aWxpemVzIGEgYmktZGltZW5zaW9uYWwgZG9zZS1sYWctcmVzcG9uc2UgZnVuY3Rpb24sIHdoaWNoIGVzc2VudGlhbGx5IGV4YW1pbmVzIG5vdCBvbmx5IHRoZSBkb3NlIGVmZmVjdCwgYnV0IHRoZSBlZmZlY3Qgb2YgdGhlIHRpbWluZyBvZiB0aGUgZG9zZS4gCgoKYGBge3IgY29tcGlsaW5nX3RlbXBfbGFnc30KIyAKIyBsYWdfdGVtcHMgPSB0ZW1wX2RhdGEgJT4lCiMgICBncm91cF9ieShkYXRlLCBob3VyKSAlPiUKIyAgIHN1bW1hcml6ZSgibWVhbl90ZW1wIiA9IG1lYW4odGVtcCwgbmEucm0gPSBUKSkgJT4lCiMgICB1bmdyb3VwKCkgJT4lCiMgICBtdXRhdGUocG9pbnRfbnVtID0gcm93X251bWJlcigpKQojIAojIHVuaXFfZGF5cyA9IGxlbmd0aCh1bmlxdWUobGFnX3RlbXBzJGRhdGUpKQojIAojIGcgPSBnYW0obWVhbl90ZW1wIH4gcyhwb2ludF9udW0sIGJzPSJjciIsIGs9dW5pcV9kYXlzICsgMTApLAojICAgICBtZXRob2QgPSAiUkVNTCIsCiMgICAgIGRhdGEgPSBsYWdfdGVtcHMpCiMgCiMgcG9pbnRzID0gc2VxKDEsIG5yb3cobGFnX3RlbXBzKSwgbGVuZ3RoLm91dCA9IGxlbmd0aChsYWdfdGVtcHMkaG91cikpCiMgCiMgZGYucmVzID0gZGYucmVzaWR1YWwoZykKIyAKIyBwcmVkX3RlbXBzID0gcHJlZGljdChnLCBuZXdkYXRhID0gbGFnX3RlbXBzLCB0eXBlID0gInJlc3BvbnNlIiwgc2UuZml0ID0gVFJVRSkKIyAKIyBsYWdfdGVtcHMgPSBsYWdfdGVtcHMgJT4lCiMgICBtdXRhdGUodHJlbmRfVCA9IHByZWRfdGVtcHMkZml0LAojICAgICAgICAgIHRyZW5kX3NlID0gcHJlZF90ZW1wcyRzZS5maXQsCiMgICAgICAgICAgdGVtcF9kaWZmID0gbWVhbl90ZW1wIC0gdHJlbmRfVCkKIyAKIyB3cml0ZS5jc3YobGFnX3RlbXBzLCBmaWxlID0gIi4vT3V0cHV0L0RhdGEvbGFnX3RlbXBzLmNzdiIsIHJvdy5uYW1lcyA9IEYpCgpgYGAKCmBgYHtyIGdlbmVyYWwtcmVsYXRpb25zaGlwfSAKCmRsbm1fZGF0YSA9IGZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGMoCiAgICAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIsCiAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIsCiAgICAiU2tpc3RvZGlhcHRvbXVzIG9yZWdvbmVuc2lzIgogICkpICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXAsIHNwX25hbWUsIGN0bWF4KSAlPiUgCiAgZ3JvdXBfYnkoY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXAsIHNwX25hbWUpICU+JSAgCiAgc3VtbWFyaXNlKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4LCBuYS5ybSA9IFQpLAogICAgICAgICAgICBzYW1wbGUgPSBuKCkpCgp0ZW1wX2RhdGEgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl90ZW1wID0gbWVhbih0ZW1wKSkgJT4lIAogIHJpZ2h0X2pvaW4oZGxubV9kYXRhLCBieSA9IGpvaW5fYnkoImRhdGUiID09ICJjb2xsZWN0aW9uX2RhdGUiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IG1lYW5fdGVtcCwgeSA9IG1lYW5fY3RtYXgpKSArIAogIGZhY2V0X3dyYXAoLn5zcF9uYW1lKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJnYW0iKSArIAogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeCA9ICJNZWFuIERhaWx5IFRlbXAuICjCsEMpIiwKICAgICAgIHkgPSAiTWVhbiBDVG1heCAowrBDKSIpICsgCnRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKYGBgCgpgYGB7cn0KCnNwX2xpc3QgPSB1bmlxdWUoZGxubV9kYXRhJHNwX25hbWUpCgpmb3IobGFnX3NwZWNpZXMgaW4gc3BfbGlzdCl7CiAgCiAgZGxubV9kYXRhX3NwID0gZGxubV9kYXRhICU+JSAKICAgIGZpbHRlcihzcF9uYW1lID09IGxhZ19zcGVjaWVzKQogIAogICMgV2UgbmVlZCB0byBlc3RpbWF0ZSBhIG1hdHJpeCBvZiBleHBvc3VyZSBoaXN0b3JpZXMgZm9yIGVhY2ggb2JzZXJ2YXRpb24uIFRoaXMgY29udGFpbnMgdGhlIHNlcmllcyBvZiBleHBvc3VyZXMgYXQgZWFjaCBsYWcgKGwpIGZvciBlYWNoIG9mIHRoZSBuIG9ic2VydmF0aW9ucywgY29uc3RyYWluZWQgYmV0d2VlbiBsMCAobWluaW11bSBsYWcpIGFuZCBMIChtYXggbGFnKS4gCgpkYXRlcyA9IGRsbm1fZGF0YV9zcCRjb2xsZWN0aW9uX2RhdGUgIyBGb3IgZWFjaCBvZiB0aGVzZSBkYXRlcywgbWFrZSBhIHZlY3RvciBvZiB0aGUgcGFzdCAzMCBkYXlzIChpbmNsdWRpbmcgdGhlIGRheSBvZiBjb2xsZWN0aW9uKS4gTk9URTogRG9uJ3QgdXNlICd1bmlxdWUnIGRhdGVzIGhlcmUgc2luY2Ugc29tZSBjb2xsZWN0aW9ucyBoYWQgbXVsdGlwbGUgc3BlY2llcwoKZXhwX2hpc3RfeiA9IGRhdGEuZnJhbWUoKQpleHBfaGlzdF90cmVuZCA9IGRhdGEuZnJhbWUoKQoKZm9yKGQgaW4gZGF0ZXMpewogIAogIGhpc3RvcnkgPSBsYWdfdGVtcHMgJT4lIAogICAgZmlsdGVyKGRhdGUgPD0gZCAmIGRhdGUgPiBkIC0gMzEpICU+JSAKICAgIGFycmFuZ2UoZGVzYyhkYXRlKSwgZGVzYyhob3VyKSkgJT4lIAogICAgbXV0YXRlKGxhZyA9IHJvd19udW1iZXIoKSAtIDEpICU+JSAKICAgIHNlbGVjdChsYWcsIG1lYW5fdGVtcCwgdGVtcF9kaWZmKQogIAogIHpfdmVjID0gc2NhbGUoaGlzdG9yeSRtZWFuX3RlbXApWywxXQogIG5hbWVzKHpfdmVjKSA9IGhpc3RvcnkkbGFnCiAgCiAgdHJlbmRfdmVjID0gaGlzdG9yeSR0ZW1wX2RpZmYKICBuYW1lcyh0cmVuZF92ZWMpID0gaGlzdG9yeSRsYWcKCiAgZXhwX2hpc3RfeiA9IGJpbmRfcm93cyhleHBfaGlzdF96LCB6X3ZlYykKICBleHBfaGlzdF90cmVuZCA9IGJpbmRfcm93cyhleHBfaGlzdF90cmVuZCwgdHJlbmRfdmVjKQogIAp9CgojcHJpbnQobWF4KGV4cF9oaXN0X3RyZW5kLCBuYS5ybSA9IFQpKQoKIyBUaGUgY3Jvc3MtYmFzaXMgZnVuY3Rpb24gZnJvbSBkbG5tIHdpbGwgdXNlIHRoZSBjbGFzcyBvZiB0aGUgeCBwYXJhbWV0ZXIgdG8gZGV0ZXJtaW5lIHdoYXQgdG8gZG8uIEluIG91ciBjYXNlLCB3ZSBuZWVkIHRvIHByb3ZpZGUgaXQgd2l0aCB0aGUgbWF0cml4IG9mIGV4cG9zdXJlIGhpc3RvcmllcyBmb3IgcmVhY2ggb2JzZXJ2YXRpb24gKHJvdykgYW5kIGxhZyAoY29sdW1uKS4gCgpjYl90ZW1wcyA9IGNyb3NzYmFzaXMoZXhwX2hpc3RfdHJlbmQsIGxhZyA9IGMoMCxkaW0oZXhwX2hpc3RfdHJlbmQpWzJdLTEpLCAKICAgICAgICAgICAgICAgICAgICAgIGFyZ3ZhciA9bGlzdChmdW49ImNyIixkZj0zKSwgCiAgICAgICAgICAgICAgICAgICAgICBhcmdsYWc9bGlzdChmdW49ImNyIixkZj0zLGludGVyY2VwdD1UKSkKCiNzdW1tYXJ5KGNiX3RlbXBzKQoKcGVuYWxpemVkX21hdCA8LSBjYlBlbihjYl90ZW1wcykKCiNmaXR0aW5nIEdBTQpsYWcuZ2FtID0gZ2FtKGRhdGEgPSBkbG5tX2RhdGFfc3AsIAogICAgICAgICAgICAgIG1lYW5fY3RtYXggfiBjYl90ZW1wcyArIGNvbGxlY3Rpb25fdGVtcCwgCiAgICAgICAgICAgICAgbWV0aG9kID0gIkdDVi5DcCIsCiAgICAgICAgICAgICAgcGFyYVBlbj1saXN0KGNiX3RlbXBzPXBlbmFsaXplZF9tYXQpKQoKIyBzdW1tYXJ5KGxhZy5nYW0pCiMgQUlDKGxhZy5nYW0pCgojZXN0aW1hdGlvbiBvZiBleHBvc3VyZXMgZWZmZWN0cwoKI2RlZmF1bHQgcGxvdHMKcHJlZF9nYW1fWnM8LWNyb3NzcHJlZChjYl90ZW1wcywgbGFnLmdhbSwgCiAgICAgICAgICAgICAgICAgICAgICAgY3VtdWw9RiwgY2VuPTAsIGNpLmxldmVsID0gMC45NSwKICAgICAgICAgICAgICAgICAgICAgICBhdD1zZXEoLTQsNCwgMC4xKSkKCnBsb3QocHJlZF9nYW1fWnMsICJjb250b3VyIikKCnBsb3QocHJlZF9nYW1fWnMsIGJvcmRlciA9IDIsIGN1bXVsPUYsCiAgICAgIHRoZXRhPTExMCxwaGk9MjAsbHRoZXRhPS04MCkKCnBsb3QocHJlZF9nYW1fWnMsICJzbGljZXMiLCAKICAgICB2YXIgPSBjKDMsLTMpLCAKICAgICBsYWcgPSBjKDEsMzM2KSwgCiAgICAgY29sID0gMikKCn0KCgoKYGBgCgoKYGBge3J9CmlmKHByZWRpY3RfdnVsbiA9PSBGKXsKICBrbml0cjo6a25pdF9leGl0KCkKfQpgYGAKCgojIyBQcmVkaWN0aW5nIFZ1bG5lcmFiaWxpdHkgClVzaW5nIHRoZSBvYnNlcnZlZCB0aGVybWFsIGxpbWl0IGRhdGEsIHdlIGNhbiBwcm9kdWNlIGEgaGluZGNhc3Qgb2YgdGhlcm1hbCBzdHJlc3MgZm9yIExha2UgQ2hhbXBsYWluIGNvcGVwb2RzLiBGb3IgdGhlc2UgaW5pdGlhbCBhc3NheXMsIHdlIHdpbGwgZGVmaW5lIHRoZXJtYWwgc3RyZXNzIGFzIGFueSB0aW1lIHdoZW4gbWF4aW11bSBkYWlseSB3YXRlciB0ZW1wZXJhdHVyZSBpcyB3aXRoaW4gMsKwQyBvZiBjb3BlcG9kIENUbWF4IG9yIGhpZ2hlci4gV2Ugd2lsbCB1c2UgdGhyZWUgZGlmZmVyZW50IHNjZW5hcmlvczogMSkgdGhlIGF2ZXJhZ2UgQ1RtYXggZm9yIGVhY2ggc3BlY2llcywgMikgQ1RtYXggcHJlZGljdGVkIHVzaW5nIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmVzLCBhbmQgMykgZm9yIHNwZWNpZXMgdGhhdCBoYXZlIHN1ZmZpY2llbnQgZGF0YSwgQ1RtYXggcHJlZGljdGVkIHVzaW5nIHdoaWNoZXZlciBlbnZpcm9ubWVudGFsIGZhY3RvciBpcyB0aGUgc3Ryb25nZXN0IGNhbmRpZGF0ZSBmb3IgZHJpdmluZyBhY2NsaW1hdGlvbi4gSW4gYWxsIGNhc2VzLCBkYXRhIGlzIGZpbHRlcmVkIHRvIGp1c3QgdGhlcm1hbCBsaW1pdHMgb2YgYWR1bHQgZmVtYWxlcy4gCgojIyMgU2NlbmFyaW8gMQpgYGB7cn0KbWVhbl9jdG1heCA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgc3VtbWFyaXplKCJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpKSAlPiUgCiAgYXJyYW5nZShtZWFuX2N0bWF4KQoKa25pdHI6OmthYmxlKG1lYW5fY3RtYXgpCmBgYAoKYGBge3J9CiMgIyBDb25zdHJ1Y3RzIHRoZSBVUkwgZm9yIHRoZSBmdWxsIHRlbXBlcmF0dXJlIGRhdGEgc2V0OyBSVU4gVEhJUyBPTkNFCiMgaGluZF91cmwgPSBjb25zdHJ1Y3ROV0lTVVJMKHNpdGVOdW1iZXJzID0gc2l0ZU51bWJlciwgcGFyYW1ldGVyQ2QgPSBwYXJhbWV0ZXJDZCwgc2VydmljZSA9ICJ1diIpCiMgCiMgaGluZF90ZW1wX2RhdGEgPSBpbXBvcnRXYXRlck1MMShoaW5kX3VybCwgYXNEYXRlVGltZSA9IFQpICU+JQojICAgbXV0YXRlKCJkYXRlIiA9IGFzLkRhdGUoZGF0ZVRpbWUpKSAlPiUKIyAgIHNlbGVjdChkYXRlLCAidGVtcCIgPSBYXzAwMDEwXzAwMDAwKQojIAojIHdyaXRlLnRhYmxlKHggPSBoaW5kX3RlbXBfZGF0YSwgZmlsZSA9ICJoaW5kY2FzdF90ZW1wcy5jc3YiLCByb3cubmFtZXMgPSBGLCBzZXAgPSAiLCIpCmBgYAoKYGBge3J9CiMgZ2dwbG90KGhpbmRfdGVtcF9kYXRhLCBhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wKSkgKyAKIyAgIGdlb21fbGluZShsaW5ld2lkdGggPSAwLjEpICsgCiMgICBsYWJzKHggPSAiRGF0ZSIsIAojICAgICAgICB5ID0gIldhdGVyIFRlbXBlcmF0dXJlICjCsEMpIikgKwojICAgdGhlbWVfbWF0dCgpCmBgYAoKSW4gdGhlIHNpbXBsZXN0IHNjZW5hcmlvLCBzcGVjaWVzIHRoZXJtYWwgbGltaXRzIGFyZSBzdGF0aWMgdGhyb3VnaCB0aW1lLCByZXByZXNlbnRlZCBieSB0aGUgYXZlcmFnZSBDVG1heCBvZiBhZHVsdCBmZW1hbGUgY29wZXBvZHMuIEluIHRoaXMgc2NlbmFyaW8sIG9ubHkgdGhyZWUgb2YgdGhlIHNldmVuIG9ic2VydmVkIHNwZWNpZXMgYXJlIGV4cG9zZWQgdG8gdGhlcm1hbCBzdHJlc3MgKHRlbXBlcmF0dXJlcyB3aXRoaW4gNcKwQyBvZiBDVG1heCkuIFRlbXBlcmF0dXJlcyBhcHByb2FjaGVkIHRoZSB0aGVybWFsIGxpbWl0IG9mICpMZXB0b2RpYXB0b211cyBzaWNpbGlzKiBvbiBhIGhhbmRmdWwgb2YgZGF5cy4gQnkgY29udHJhc3QsICpTZW5lY2VsbGEgY2FsYW5vaWRlcyogYW5kICpMaW1ub2NhbGFudXMgbWFjcnVydXMqIHdlcmUgYm90aCBleHBvc2VkIHRvIHN1YnN0YW50aWFsIHRoZXJtYWwgc3RyZXNzIHRocm91Z2hvdXQgYSBsYXJnZSBwb3J0aW9uIG9mIHRoZSB5ZWFyLCBsaWtlbHkgZXhwbGFpbmluZyB3aHkgdGhlc2Ugc3BlY2llcyBhcmUgYWJzZW50IGZyb20gdGhlIGNvbW11bml0eSBmb3IgdGhlIHN1bW1lciBhbmQgZmFsbCBwZXJpb2RzLiAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQpoaW5kMV9kYXRhID0gaGluZF90ZW1wX2RhdGEgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpemUoImRhaWx5X21heCIgPSBtYXgodGVtcCksCiAgICAgICAgICAgICJkYWlseV9tZWFuIiA9IG1lYW4odGVtcCksKSAlPiUgCiAgYmluZF9jb2xzKHBpdm90X3dpZGVyKG1lYW5fY3RtYXgsIG5hbWVzX2Zyb20gPSBzcF9uYW1lLCB2YWx1ZXNfZnJvbSA9IG1lYW5fY3RtYXgpKSAlPiUgIAogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSwgLWRhaWx5X21heCwgLWRhaWx5X21lYW4pLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJzcGVjaWVzIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJtZWFuX2N0bWF4IikgJT4lICAKICBtdXRhdGUobGltX2RpZmYgPSBtZWFuX2N0bWF4IC0gZGFpbHlfbWF4KSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpLAogICAgICAgICAibWV0aG9kIiA9ICJOb19hY2NsaW1hdGlvbiIpCgpoaW5kX2RhaWx5X3RlbXBfZGF0YSA9IGhpbmRfdGVtcF9kYXRhICU+JQogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RlbXAgPSBtZWFuKHRlbXApLAogICAgICAgICAgICBtZWRfdGVtcCA9IG1lZGlhbih0ZW1wKSwKICAgICAgICAgICAgdmFyX3RlbXAgPSB2YXIodGVtcCksIAogICAgICAgICAgICBtaW5fdGVtcCA9IG1pbih0ZW1wKSwgCiAgICAgICAgICAgIG1heF90ZW1wID0gbWF4KHRlbXApKSAlPiUgCiAgbXV0YXRlKCJyYW5nZV90ZW1wIiA9IG1heF90ZW1wIC0gbWluX3RlbXApCgojdGFibGUoaGluZDFfZGF0YSRzcGVjaWVzKQoKaGluZDFfZGF0YSAlPiUgCiAgZmlsdGVyKGxpbV9kaWZmIDw9IDUpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gZG95LCB5ID0gbGltX2RpZmYsIGNvbG91ciA9IHNwZWNpZXMpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCAKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZ2VvbV9zbW9vdGgoc2UgPSBGKSArIAogIGxhYnMoeCA9ICJEYXkgb2YgWWVhciIsIAogICAgICAgeSA9ICJQcmVkaWN0ZWQgV2FybWluZyBUb2xlcmFuY2UgXG4owrBDIEFib3ZlIERhaWx5IE1heCkiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKIyMjIFNjZW5hcmlvIDIKSW4gdGhlIHNlY29uZCBzY2VuYXJpbywgdGhlcm1hbCBsaW1pdHMgdmFyeSB3aXRoaW4gYW5kIGJldHdlZW4gc3BlY2llcy4gQSBzaW1wbGUgbW9kZWwgaXMgdXNlZCB0byBwcmVkaWN0IHNwZWNpZXMgdGhlcm1hbCBsaW1pdHMgYmFzZWQgb24gbWVhbiBkYWlseSB0ZW1wZXJhdHVyZSAoQ1RtYXggYXMgYSBmdW5jdGlvbiBvZiBzcGVjaWVzIGFuZCBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLCBidXQgd2l0aG91dCB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGVzZSB0d28gZmFjdG9ycykuIFRoZXNlIHByZWRpY3RlZCB0aGVybWFsIGxpbWl0cyBhcmUgdGhlbiBjb21wYXJlZCBhZ2FpbnN0IHRoZSBtYXhpbXVtIGRhaWx5IHRlbXBlcmF0dXJlIHRvIGVzdGltYXRlIHRoZXJtYWwgc3RyZXNzLCBhcyBpbiBTY2VuYXJpbyAxLiBJbmNsdWRpbmcgdGhpcyBzaW1wbGUgZm9ybSBvZiBhY2NsaW1hdGlvbiBpbiB0aGUgbW9kZWwgcmVkdWNlZCB0aGUgZGVncmVlIG9mIHRoZXJtYWwgc3RyZXNzIGZvciBlYWNoIHNwZWNpZXMsIGVsaW1pbmF0aW5nIGl0IGVudGlyZWx5IGZvciAqTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyouIE5vdGUgdGhhdCB0aGUgbWFnbml0dWRlIG9mIHRoZSBwcmVkaWN0ZWQgc3RyZXNzIGlzICBsb3cgZW5vdWdoIHRoYXQgcmVtb3ZpbmcgdGhlIDXCsEMgYnVmZmVyIGFyb3VuZCB0aGUgcHJlZGljdGVkIHRoZXJtYWwgbGltaXRzIHdvdWxkIGFjdHVhbGx5IGxpbWl0IHByZWRpY3RlZCB0aGVybWFsIHN0cmVzcyB0byBqdXN0IGEgZmV3IGRheXMgZm9yICpTZW5lY2VsbGEgY2FsYW5vaWRlcyouIAoKYGBge3IgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTB9CmhpbmRjYXN0X21vZGVsMSA9IGxtKGRhdGEgPSBmaWx0ZXIoZnVsbF9kYXRhLCBzZXggPT0gImZlbWFsZSIpLAogICAgICAgICAgICAgICAgICAgICBjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCArIHNwX25hbWUpCgpoaW5kMl9kYXRhID0gaGluZF90ZW1wX2RhdGEgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpemUoImNvbGxlY3Rpb25fdGVtcCIgPSBtZWFuKHRlbXApLAogICAgICAgICAgICAiZGFpbHlfbWF4IiA9IG1heCh0ZW1wKSkgJT4lIAogIGJpbmRfY29scygKICAgIHBpdm90X3dpZGVyKG1lYW5fY3RtYXgsIAogICAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNwX25hbWUsIAogICAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBtZWFuX2N0bWF4KSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSwgLWRhaWx5X21heCwgLWNvbGxlY3Rpb25fdGVtcCksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInNwX25hbWUiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIm1lYW5fY3RtYXgiKSAlPiUgCiAgc2VsZWN0KC1tZWFuX2N0bWF4KSAlPiUgCiAgbXV0YXRlKCJwcmVkX2N0bWF4IiA9IHByZWRpY3QubG0gKGhpbmRjYXN0X21vZGVsMSwgbmV3ZGF0YSA9IC4pKSAlPiUgCiAgc2VsZWN0KGRhdGUsICJkYWlseV9tZWFuIiA9IGNvbGxlY3Rpb25fdGVtcCwgZGFpbHlfbWF4LCAic3BlY2llcyIgPSBzcF9uYW1lLCBwcmVkX2N0bWF4KSAlPiUgCiAgbXV0YXRlKGxpbV9kaWZmID0gcHJlZF9jdG1heCAtIGRhaWx5X21heCkgJT4lIAogICNmaWx0ZXIobGltX2RpZmYgPD0gMCkgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShkYXRlKSwKICAgICAgICAgIm1ldGhvZCIgPSAiQ29uc3RhbnRfYWNjbGltYXRpb24iKQoKIyBnZ3Bsb3QoaGluZDJfZGF0YSwgYWVzKHggPSBkYWlseV9tZWFuLCB5ID0gcHJlZF9jdG1heCwgY29sb3VyID0gc3BlY2llcykpICsKIyAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpIAoKIyB0YWJsZShoaW5kMl9kYXRhJHNwZWNpZXMpCmhpbmQyX2RhdGEgJT4lICAKICBmaWx0ZXIobGltX2RpZmYgPD0gNSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBkb3ksIHkgPSBsaW1fZGlmZiwgY29sb3VyID0gc3BlY2llcykpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUsIAogICAgICAgICAgICAgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsKICBnZW9tX3Ntb290aCgpICsgCiAgbGFicyh4ID0gIkRheSBvZiBZZWFyIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCBXYXJtaW5nIFRvbGVyYW5jZSBcbijCsEMgQWJvdmUgRGFpbHkgTWF4KSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgojIyMgU2NlbmFyaW8gMwpUaGUgZmluYWwgc2NlbmFyaW8gYWxsb3dzIHRoZSBlbnZpcm9ubWVudGFsIHZhcmlhYmxlIHVzZWQgdG8gcHJlZGljdCBDVG1heCB0byB2YXJ5IGJldHdlZW4gc3BlY2llcy4gRm9yIHNwZWNpZXMgb2JzZXJ2ZWQgaW4gZmV3ZXIgdGhhbiA1IGNvbGxlY3Rpb25zLCB3ZSB1c2UgdGhlIHNhbWUgYXBwcm9hY2ggYXMgaW4gU2NlbmFyaW8gMi4gRm9yIHNwZWNpZXMgb2JzZXJ2ZWQgaW4gbW9yZSB0aGFuIDUgY29sbGVjdGlvbnMsIGhvd2V2ZXIsIHRoZSBmYWN0b3Igd2l0aCB0aGUgc3Ryb25nZXN0IGNvcnJlbGF0aW9uIHdpdGggQ1RtYXggaXMgdXNlZCB0byBwcmVkaWN0IHRoZXJtYWwgbGltaXRzLiBUaGVzZSBmYWN0b3JzIGFyZSBpbmNsdWRlZCBiZWxvdy4KCmBgYHtyfQpoaW5kX3ByZWRzID0gY29ycl92YWxzICU+JSAgCiAgZmlsdGVyKHNpZyA9PSAiU2lnLiIpICU+JSAKICBkcm9wX25hKGNvcnJlbGF0aW9uKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lCiAgYXJyYW5nZShkZXNjKGNvcnJlbGF0aW9uKSkgJT4lIAogIHNsaWNlX2hlYWQobiA9IDEpICU+JSAKICBzZWxlY3QoIlNwZWNpZXMiID0gc3BfbmFtZSwgIlByZWRpY3RvciIgPSBwYXJhbWV0ZXIsICJEdXJhdGlvbiIgPSBkdXJhdGlvbiwgIkNvcnJlbGF0aW9uIiA9IGNvcnJlbGF0aW9uLCAiUC1WYWx1ZSIgPSBwLnZhbHVlKQoKa25pdHI6OmthYmxlKGhpbmRfcHJlZHMsIGFsaWduID0gImMiKQpgYGAKCmBgYHtyfQpoaW5kM19kYXRhID0gaGluZDJfZGF0YSAlPiUgIyBDb250YWlucyBkYXRhIGZvciBzcGVjaWVzIHRoYXQgd29uJ3QgY2hhbmdlIGZyb20gc2NlbmFyaW8gMgogIGZpbHRlcighKHNwZWNpZXMgJWluJSBjb3JyX3ZhbHMkc3BfbmFtZSkpCgpwcmVkc190b19wdWxsID0gaGluZF9wcmVkcyAlPiUgIAogIHNlbGVjdChTcGVjaWVzLCBQcmVkaWN0b3IsIER1cmF0aW9uKSAKCmZvcihpIGluIDE6bGVuZ3RoKHByZWRzX3RvX3B1bGwkU3BlY2llcykpewogIAogIGlmKHByZWRzX3RvX3B1bGwkRHVyYXRpb25baV0gPT0gInByaW9yIil7ICNUaGUgcHJpb3IgZGF5IHRlbXBlcmF0dXJlIG1ldHJpY3Mgc2hvdWxkIGJlIHVzZWQKICAgIGR1cmF0aW9uID0gTkEKICAgIAogICAgcHJlZGljdG9ycyA9IGhpbmRfZGFpbHlfdGVtcF9kYXRhICU+JSAKICAgICAgbXV0YXRlKGRhdGUgPSBkYXRlICsgMSkgCiAgICAKICAgIHBhcmFtZXRlciA9IHByZWRzX3RvX3B1bGwkUHJlZGljdG9yW2ldCiAgICAKICAgIG1vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lCiAgICAgIGZpbHRlcihzcF9uYW1lICVpbiUgcHJlZHNfdG9fcHVsbCRTcGVjaWVzW2ldKSAlPiUgCiAgICAgIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICAgICAgbXV0YXRlKGNvbGxlY3Rpb25fZGF0ZSA9IGFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAogICAgICBpbm5lcl9qb2luKHByZWRpY3RvcnMsIGpvaW5fYnkoY29sbGVjdGlvbl9kYXRlID09IGRhdGUpKSAlPiUgIAogICAgICBzZWxlY3QoY3RtYXgsIGNvbnRhaW5zKHBhcmFtZXRlcikpCiAgICAKICAgIGlmKGRpbShtb2RlbF9kYXRhKVsyXSA9PSAyKXsKICAgICAgaGluZC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgIGN0bWF4IH4gLikKICAgICAgCiAgICAgIHNwX2RhdGEgPSBwcmVkaWN0b3JzICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgY29udGFpbnMocGFyYW1ldGVyKSkgJT4lIAogICAgICAgIG11dGF0ZShwcmVkX2N0bWF4ID0gcHJlZGljdChoaW5kLm1vZGVsLCBuZXdkYXRhID0gLikpICU+JSAgCiAgICAgICAgc2VsZWN0KGRhdGUsIHByZWRfY3RtYXgpICU+JSAKICAgICAgICBpbm5lcl9qb2luKGhpbmRfZGFpbHlfdGVtcF9kYXRhLCBieSA9IGMoImRhdGUiKSkgJT4lIAogICAgICAgIG11dGF0ZSgic3BlY2llcyIgPSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0sCiAgICAgICAgICAgICAgICJkb3kiID0geWRheShkYXRlKSwKICAgICAgICAgICAgICAgbGltX2RpZmYgPSBwcmVkX2N0bWF4IC0gbWF4X3RlbXApICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgZGFpbHlfbWVhbiA9IG1lYW5fdGVtcCwgZGFpbHlfbWF4ID0gbWF4X3RlbXAsIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBkb3kpCiAgICAgIAogICAgICBoaW5kM19kYXRhID0gYmluZF9yb3dzKGhpbmQzX2RhdGEsIHNwX2RhdGEpCiAgICB9ZWxzZXsKICAgICAgcHJpbnQoIlRvbyBtYW55IGNvbHVtbnMgc2VsZWN0ZWQiKQogICAgfQogICAgCiAgICAKICB9ZWxzZXsKICAgIGR1cmF0aW9uID0gYXMubnVtZXJpYyhwcmVkc190b19wdWxsJER1cmF0aW9uW2ldKQogIH0KICAKICBpZihwcmVkc190b19wdWxsJER1cmF0aW9uW2ldICE9ICJwcmlvciIgJiBpcy5uYShkdXJhdGlvbikpeyAjRGFpbHkgdGVtcGVyYXR1cmVzIHNob3VsZCBiZSB1c2VkLCBhcyBpbiBTY2VuYXJpbyAyCiAgICBzcF9kYXRhID0gaGluZDJfZGF0YSAlPiUgCiAgICAgIGZpbHRlcihzcGVjaWVzID09IHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSkKICAgIAogICAgaGluZDNfZGF0YSA9IGJpbmRfcm93cyhoaW5kM19kYXRhLCBzcF9kYXRhKQogIH0KICAKICBpZihpcy5udW1lcmljKGR1cmF0aW9uKSl7CiAgICAjTmVpdGhlciB0aGUgcHJpb3IgZGF5IG5vciBkYXkgb2YgbWV0cmljcyBzaG91bGQgYmUgdXNlZDsgdXNlIGR1cmF0aW9uIGFzIG5fZGF5cwogICAgCiAgICBwcmVkaWN0b3JzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gaGluZF9kYWlseV90ZW1wX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gaGluZF90ZW1wX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IGR1cmF0aW9uKQogICAgCiAgICBwYXJhbWV0ZXIgPSBwcmVkc190b19wdWxsJFByZWRpY3RvcltpXQogICAgCiAgICBtb2RlbF9kYXRhID0gZnVsbF9kYXRhICU+JQogICAgICBmaWx0ZXIoc3BfbmFtZSAlaW4lIHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSkgJT4lIAogICAgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgICAgIG11dGF0ZShjb2xsZWN0aW9uX2RhdGUgPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICAgICAgaW5uZXJfam9pbihwcmVkaWN0b3JzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lICAKICAgICAgc2VsZWN0KGN0bWF4LCBjb250YWlucyhwYXN0ZSgiZGF5XyIsIHBhcmFtZXRlciwgc2VwID0gIiIpKSkKICAgIAogICAgaWYoZGltKG1vZGVsX2RhdGEpWzJdID09IDIpewogICAgICBoaW5kLm1vZGVsID0gbG0oZGF0YSA9IG1vZGVsX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgY3RtYXggfiAuKQogICAgICAKICAgICAgc3BfZGF0YSA9IHByZWRpY3RvcnMgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBjb250YWlucyhwYXJhbWV0ZXIpKSAlPiUgCiAgICAgICAgbXV0YXRlKHByZWRfY3RtYXggPSBwcmVkaWN0KGhpbmQubW9kZWwsIG5ld2RhdGEgPSAuKSkgJT4lICAKICAgICAgICBzZWxlY3QoZGF0ZSwgcHJlZF9jdG1heCkgJT4lIAogICAgICAgIGlubmVyX2pvaW4oaGluZF9kYWlseV90ZW1wX2RhdGEsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgCiAgICAgICAgbXV0YXRlKCJzcGVjaWVzIiA9IHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSwKICAgICAgICAgICAgICAgImRveSIgPSB5ZGF5KGRhdGUpLAogICAgICAgICAgICAgICBsaW1fZGlmZiA9IHByZWRfY3RtYXggLSBtYXhfdGVtcCkgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBkYWlseV9tZWFuID0gbWVhbl90ZW1wLCBkYWlseV9tYXggPSBtYXhfdGVtcCwgc3BlY2llcywgcHJlZF9jdG1heCwgbGltX2RpZmYsIGRveSkKICAgICAgCiAgICAgIGhpbmQzX2RhdGEgPSBiaW5kX3Jvd3MoaGluZDNfZGF0YSwgc3BfZGF0YSkKICAgICAgCiAgICB9ZWxzZXsKICAgICAgcHJpbnQoIlRvbyBtYW55IGNvbHVtbnMgc2VsZWN0ZWQiKQogICAgfQogICAgCiAgfQp9CgpoaW5kM19kYXRhID0gaGluZDNfZGF0YSAlPiUgCiAgbXV0YXRlKCJtZXRob2QiID0gIlZhcmlhYmxlX2FjY2xpbWF0aW9uIikKYGBgCgpUaGlzIHRoaXJkIGFwcHJvYWNoIGRpZCBub3QgYWZmZWN0IHRoZSBwcmVkaWN0ZWQgcGF0dGVybnMgaW4gKkxpbW5vY2FsYW51cyogb3IgKlNlbmVjZWxsYSogKG5laXRoZXIgc3BlY2llcyBoYXMgYmVlbiBvYnNlcnZlZCBpbiBlbm91Z2ggY29sbGVjdGlvbnMgdG8gZXN0aW1hdGUgdGhlIGVmZmVjdHMgb2YgZGlmZmVyZW50IGVudmlyb25tZW50YWwgZmFjdG9ycykuIENoYW5naW5nIHRoZSBhY2NsaW1hdGlvbiBhcHByb2FjaCBkaWQgYWZmZWN0IHBhdHRlcm5zIGluIHRoZXJtYWwgbGltaXRzIGluIHRoZSBvdGhlciBzcGVjaWVzIHRob3VnaC4gVGhlIGZpZ3VyZSBiZWxvdyBzaG93cyBob3cgcHJlZGljdGVkIHdhcm1pbmcgdG9sZXJhbmNlIHZhcmllcyBvdmVyIHRoZSB5ZWFyIGluIHRoZSBzZXZlbiBzcGVjaWVzLCBiYXNlZCBvbiB0aGUgdGhyZWUgZGlmZmVyZW50IHByZWRpY3Rpb24gbWV0aG9kcy4gSW4gZ2VuZXJhbCwgY29uc3RhbnQgdGhlcm1hbCBsaW1pdHMgKHRoZSAnbm8gYWNjbGltYXRpb24nIG1ldGhvZCkgcmVzdWx0ZWQgaW4gbGFyZ2VyIHdhcm1pbmcgdG9sZXJhbmNlIGR1cmluZyB0aGUgd2ludGVyIGFuZCBsb3dlciB3YXJtaW5nIHRvbGVyYW5jZSBkdXJpbmcgdGhlIHN1bW1lciwgYWx0aG91Z2ggdGhpcyBlZmZlY3Qgd2FzIHNtYWxsIGluIG1vc3Qgc3BlY2llcy4gICAgIAoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwfQpzeW50aGVzaXMgPSBiaW5kX3Jvd3MoCiAgc2VsZWN0KGhpbmQxX2RhdGEsIGRhdGUsIGRveSwgZGFpbHlfbWVhbiwgZGFpbHlfbWF4LCBzcGVjaWVzLCAicHJlZF9jdG1heCIgPSBtZWFuX2N0bWF4LCBsaW1fZGlmZiwgbWV0aG9kKSwKICBzZWxlY3QoaGluZDJfZGF0YSwgZGF0ZSwgZG95LCBkYWlseV9tZWFuLCBkYWlseV9tYXgsICBzcGVjaWVzLCBwcmVkX2N0bWF4LCBsaW1fZGlmZiwgbWV0aG9kKSwKICBzZWxlY3QoaGluZDNfZGF0YSwgZGF0ZSwgZG95LCBkYWlseV9tZWFuLCBkYWlseV9tYXgsICBzcGVjaWVzLCBwcmVkX2N0bWF4LCBsaW1fZGlmZiwgbWV0aG9kKSkgJT4lIAogIG11dGF0ZShtZXRob2QgPSBmY3RfcmVsZXZlbChtZXRob2QsICJOb19hY2NsaW1hdGlvbiIsICJDb25zdGFudF9hY2NsaW1hdGlvbiIsICJWYXJpYWJsZV9hY2NsaW1hdGlvbiIpKQoKY2xpbWF0b2xvZ3kgPSBzeW50aGVzaXMgJT4lIAogIGdyb3VwX2J5KHNwZWNpZXMsIGRveSwgbWV0aG9kKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9kaWZmIiA9IG1lYW4obGltX2RpZmYpLAogICAgICAgICAgICAibWluX2RpZmYiID0gbWluKGxpbV9kaWZmKSwKICAgICAgICAgICAgIm1heF9kaWZmIiA9IG1heChsaW1fZGlmZikpICU+JSAKICBtdXRhdGUobWV0aG9kID0gZmN0X3JlbGV2ZWwobWV0aG9kLCAiTm9fYWNjbGltYXRpb24iLCAiQ29uc3RhbnRfYWNjbGltYXRpb24iLCAiVmFyaWFibGVfYWNjbGltYXRpb24iKSkKCmFjY19lZmZlY3RzID0gc3ludGhlc2lzICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyhkYXRlLCBzcGVjaWVzLCBkb3kpLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gbWV0aG9kLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGxpbV9kaWZmKSAlPiUgIAogIG11dGF0ZSgiY29uc3RfYWNjX2VmZmVjdCIgPSBDb25zdGFudF9hY2NsaW1hdGlvbiAtIE5vX2FjY2xpbWF0aW9uLAogICAgICAgICAidmFyX2FjY19lZmZlY3QiID0gVmFyaWFibGVfYWNjbGltYXRpb24gLSBOb19hY2NsaW1hdGlvbikKCmdncGxvdChzeW50aGVzaXMsIGFlcyh4ID0gZG95LCB5ID0gbGltX2RpZmYsIGNvbG91ciA9IG1ldGhvZCkpICsgCiAgZmFjZXRfd3JhcChzcGVjaWVzfi4pICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiUHJlZGljdGVkIFdhcm1pbmcgVG9sZXJhbmNlICjCsEMgQWJvdmUgRGFpbHkgTWF4KSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKGJhc2Vfc2l6ZSA9IDE4KSArIAogIHRoZW1lKHN0cmlwLnRleHQueC50b3AgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkKYGBgCgpgYGB7ciwgaW5jbHVkZSA9IEZ9CnllYXJseV9zdW1tYXJ5ID0gc3ludGhlc2lzICU+JSAgCiAgbXV0YXRlKCJ5ZWFyIiA9IHllYXIoZGF0ZSkpICU+JSAKICBncm91cF9ieShzcGVjaWVzLCB5ZWFyLCBtZXRob2QpICU+JSAKICBzdW1tYXJpc2UoIm1pbl93dCIgPSBtaW4obGltX2RpZmYpLAogICAgICAgICAgICAibWF4X3d0IiA9IG1heChsaW1fZGlmZikpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMobWluX3d0LCBtYXhfd3QpLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAibWV0cmljIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ3dCIpCgpnZ3Bsb3QoeWVhcmx5X3N1bW1hcnksIGFlcyh4ID0gbWV0aG9kLCB5ID0gd3QsIGNvbG91ciA9IG1ldHJpYykpICsgCiAgZmFjZXRfd3JhcCgufnNwZWNpZXMpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKYGBgCgo=